//============================================================================================
/**
 * @file	before_poketch.c
 * @brief	ポケッチ取得以前画面（フィールドメインメニュー）
 * @author	taya GAME FREAK inc.
 * @author	(GS) mori akito さん >> hosaka genya
 *
 * @note	ボタン操作でアプリを抜けた際の画面構築時、fsys->sublcd_menu_onはfld_menu.cによってワイプ中に1が入る。
 * @note	初期化関数の中ではまだ0のため、この場合は初期化判定にfsys->sublcd_menu_onを使用することはは出来ない。
 * @note	レポートやダウジングの場合はフィールドを維持したまま画面遷移するので、この限りではない。
 */
//============================================================================================

// でんわテスト
//#define DEBUG_PHONE

#include "common.h"
#include "tcb.h"
#include "system\arc_util.h"
#include "system/clact_tool.h"
#include "system/lib_pack.h"
#include "system/snd_tool.h"
#include "system/fontoam.h"
#include "system/fontproc.h"
#include "system/wipe.h"
#include "system/clact_tool.h"
#include "savedata/savedata.h"
#include "field/location.h"
#include "field/situation.h"
#include "field/player.h"
#include "../situation_local.h"
#include "gflib/touchpanel.h"
#include "field/poketch.h"
#include "field/syswork.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_fieldmenu.h"
#include "system\wordset.h"
#include "system\msgdata_util.h"
#include "field/sysflag.h"
#include "field/fld_pmtel.h"
#include "field/field_clact.h"
#include "field/fld_menu.h"
#include "field/field_poketch.h"
#include "field/fld_mushitori.h"
#include "itemtool/myitem.h"
#include "itemtool/item.h"
#include "poketool/pokeicon.h"
#include "AMProtect/AMProtect.h"

#include "../sxy.h"
#include "../ev_check.h"
#include "../scr_offset.h"
#include "../script.h"
#include "../pokepark_sys.h"
#include "../b_tower_ev.h"

#include "poketch_arc.h"

// 通信情報取得用
#include "communication/comm_system.h"
#include "../comm_field_state.h"
#include "../comm_player.h"

#include "gs_bugfix.h"

#ifdef TCB_COUNT_DEBUG
	// 「メニュー」の変わりに heap_size を表示 (FINAL_ROMでのデバッグ用)
	#define PRINT_HEAP_SIZE
#endif

enum{
	MENU_POS_01 = 0,
	MENU_POS_02,
	MENU_POS_03,
	MENU_POS_04,
	MENU_POS_05,
	MENU_POS_06,
	MENU_POS_07,
	MENU_POS_08,	// ※必ず情報表示のみ
	MENU_MAX,
};

#define MENU_ICON_NUM	( 7 )

//--------------------------------------------------------------
/// SUBLCDメニューモード
//==============================================================
// 他ファイルでマジックナンバーで使われているため現状変更不可
enum
{
	SUBLCD_MENU_OFF = 0,		// OFF状態
	SUBLCD_MENU_ON_INIT,		// ON状態 初期化
	SUBLCD_MENU_ON,				// ON状態 入力待ち
	SUBLCD_MENU_FROM_FIELD,		// フィールド維持復帰（レポート、ダウジング）
	SUBLCD_MENU_TO_FIELD,
	SUBLCD_MENU_MAX,
};

//--------------------------------------------------------------
///	メニューモード
//==============================================================
enum
{
	MENU_MODE_NORMAL = 0,
	MENU_MODE_SAFARI,
	MENU_MODE_MUSHITORI,
	MENU_MODE_PARK,
	MENU_MODE_UNION,
	MENU_MODE_COLOSSEUM,		///< コロシアム
	MENU_MODE_BTL_TOWER_SALON,	///< バトルタワーサロン
	MENU_MODE_MAX,
} MENU_MODE;

// CLACTで定義しているセルが大きすぎてサブ画面に影響がでてしまうので離してみる
#define SUBLCD_MENU_SUB_ACTOR_DISTANCE 	(256*FX32_ONE)

// CellActorに処理させるリソースマネージャの種類の数（＝マルチセル・マルチセルアニメは使用しない）
#define CLACT_RESOURCE_TYPE_NUM		( 4 )

//--------------------------------------------------------------
///	リソースNO
//==============================================================
enum
{
	// 0-6 : メニューリスト
	RES_NO_SHORTCUT1 = 7,
	RES_NO_SHORTCUT2 = 8,
	RES_NO_BUTTON = 9,
	RES_NO_BALL = 10,
	// システムメニューのセルアクターが読み込むキャラ・パレット（セットで）の総数
	CLACT_RESOURCE_CHARA_NUM = 11,

	OAM_DISP_DIFF = -2, // メニューOAM表示オフセット
};

// #define SUBLCD_OAM_NUM			( 13 )
// #define CLACT_RESOURCE_TBL_NUM	(  2 )

#define HEAPID_SUBLCD_MENU		( HEAPID_POKETCH_APP )
#define ARC_SUBLCDMENU_GRA		( ARC_POKETCH_IMG )


// OAMに書き込む文字列用ウインドウの幅定義（キャラ単位）
#define SYSTEM_STRING1_W	(  8 )	// 「Xメニュー」
#define SYSTEM_STRING2_W	( 12 )	// 「ボタンそうさ」
#define SYSTEM_STRING_H		(  2 )
#define SYSTEM_OAM_STRING_W	(  4 )
#define OBJ_VRAM_WORD_TRANS_SIZE	(SYSTEM_OAM_STRING_W*SYSTEM_STRING_H*0x20)
#define OBJ_CHARA_VRAM_OFFSET ( 16*4 )

#define MENU_STRING_X			(   3 )
#define MENU_STRING_Y			(   1 )
#define MENU_STRING_W			(   9 )
#define MENU_STRING_H			(   2 )
#define MENU_STRING_VRAM_OFFSET	( 32*6 )	//

#define MENU_STRING_PAL			(   4 )
#define MENU_STRING_PAL_OFFSET  ( MENU_STRING_PAL*32 )

#define ABUTTON_WIN_X	( 24 )
#define ABUTTON_WIN_Y	( 20 )
#define ABUTTON_WIN_W	(  8 )
#define ABUTTON_WIN_H	(  2 )
#define ABUTTON_VRAM_OFFSET		( MENU_STRING_VRAM_OFFSET+MENU_STRING_W*MENU_STRING_H)

#define XBUTTON_WIN_X	(  8 )
#define XBUTTON_WIN_Y	(  0 )
#define XBUTTON_WIN_W	( 10 )
#define XBUTTON_WIN_H	(  2 )
#define XBUTTON_VRAM_OFFSET		( ABUTTON_VRAM_OFFSET+ABUTTON_WIN_W*ABUTTON_WIN_H)

// メインメニューアイコン説明BMPキャラ単位座標
#define EXPLAIN0_WIN_X	(  1 )
#define EXPLAIN0_WIN_Y	(  6 )
#define EXPLAIN1_WIN_X	(  1 )
#define EXPLAIN1_WIN_Y	( 11 )
#define EXPLAIN2_WIN_X	(  1 )
#define EXPLAIN2_WIN_Y	( 16 )
#define EXPLAIN3_WIN_X	(  1 )
#define EXPLAIN3_WIN_Y	( 21 )
#define EXPLAIN4_WIN_X	( 11 )
#define EXPLAIN4_WIN_Y	(  6 )
#define EXPLAIN5_WIN_X	( 11 )
#define EXPLAIN5_WIN_Y	( 11 )
#define EXPLAIN6_WIN_X	( 11 )
#define EXPLAIN6_WIN_Y	( 16 )
#define EXPLAIN7_WIN_X	( 11 )
#define EXPLAIN7_WIN_Y	( 21 )
#define EXPLAIN_WIN_W	(  9 )
#define EXPLAIN_WIN_H	(  2 )
#define EXPLAIN_VRAM_OFFSET		( XBUTTON_VRAM_OFFSET+XBUTTON_WIN_W*XBUTTON_WIN_H)

#define MENU_EXPLAIN_NUM	( 8 )

// ボール個数
#define BALL_NUM_POS6_Y (14)	// 6個目のメニュー位置
#define BALL_NUM_POS7_Y (19)	// 7個目のメニュー位置
#define BALL_NUM_POS_X (14)
#define BALL_NUM_WIN_W (6)
#define BALL_NUM_WIN_H (2)
#define BALL_NUM_VRAM_OFFSET	( EXPLAIN_VRAM_OFFSET+EXPLAIN_WIN_W*EXPLAIN_WIN_H*MENU_EXPLAIN_NUM)

// 文字列座標からのボールOBJ座標オフセット
#define BALL_OBJ_OFS_DOT_X (-10+OAM_DISP_DIFF)
#define BALL_OBJ_OFS_DOT_Y (-6+OAM_DISP_DIFF)

// ポケモンレベル
#define POKE_LV_WIN_PX (12)
#define POKE_LV_WIN_PY (21)
#define POKE_LV_WIN_W (6)
#define POKE_LV_WIN_H (2)
#define POKE_LV_VRAM_OFFSET		( BALL_NUM_VRAM_OFFSET+BALL_NUM_WIN_W*BALL_NUM_WIN_H )
#define POKE_LV_OFS_X (4)

// リソース管理ID開始値
#define SYSMENU_RES_ID		( 100)

#define ICON_WIN_WRITE  ( 0 )
#define PHONE_WIN_WRITE ( 1 )
#define PHONE_WIN_CLEAR ( 2 )

// 電話着信ウィンドウの位置
#define TEL_WIN_PX ( 11 )
#define TEL_WIN_PY ( 19 )

// 虫ポケモン表示座標
#define MUSHI_POKE_PX (104)
#define MUSHI_POKE_PY (104+32)

//--------------------------------------------------------------
///	主人公がＡボタンでできる事
//==============================================================
enum{
	ACTION_TALK=0,		// はなす
	ACTION_SEARCH,		// しらべる
	ACTION_DECIDE,		// けってい
	ACTION_FISHING,		// つり
	ACTION_CONTINUE,	// つぎへ
	ACTION_STRING_MAX,	// タッチＡボタンの書き換わる文字列の種類の数
};

static const u32 action_str_tbl[ ACTION_STRING_MAX ]={
	msg_menu_17,	// 「はなす」
	msg_menu_18,	// 「しらべる」
	msg_menu_19,	// 「けってい」←使わない？
	msg_menu_22,	// 「つり」
	msg_menu_23,	// 「つぎへ」
};

// セルアクター参照用定義
enum{
	FMENU_OAM_POS_1 = 0,
	FMENU_OAM_POS_2,
	FMENU_OAM_POS_3,
	FMENU_OAM_POS_4,
	FMENU_OAM_POS_5,
	FMENU_OAM_POS_6,
	FMENU_OAM_POS_7,
	FMENU_OAM_SHORTCUT1,
	FMENU_OAM_SHORTCUT2,
	FMENU_OAM_SHORTCUT1_BG,
	FMENU_OAM_SHORTCUT2_BG,
	FMENU_OAM_B_BUTTON,
	FMENU_OAM_A_BUTTON,
	FMENU_OAM_DASH_GEAR,
	FMENU_OAM_X_ICON,
	FMENU_OAM_BALL,
//	FMENU_OAM_MUSHIPOKE,
	FMENU_OAM_MAX,
	FMENU_OAM_MUSHIPOKE = FMENU_OAM_POS_7,
	FMENU_OAM_POKEGEAR = FMENU_OAM_POS_4, // キメウチであまり好ましくないが、4固定で問題ないはず
};

#define MENU_ALL_OAM_NUM	( FMENU_OAM_MAX )

//------------------------------------------------------------------
/// 画面に表示されるメニューの情報
//------------------------------------------------------------------
typedef struct{
	u8 		exist;
	STRBUF	*String;
}MENU_EXIST_TBL;


//--------------------------------------------------------------
///	電話着信モジュール管理ワーク
//==============================================================
typedef struct {
	// [IN]
	GF_BGL_INI		*bgl;
	FLD_PMTEL_WORK	*pmtel;			// ポケギア電話ワーク
	CLACT_WORK_PTR	MenuAct;		// ポケギアのメニュー項目
	// [PRIVATE]
	GF_BGL_BMPWIN	MenuBmp;			// 選択中の項目を説明する文章を表示するBMPWIN領域
	BOOL			tel_flag;			// 電話呼び出し状態の保存ワーク
} PHONE_WORK;

//------------------------------------------------------------------
/// 構造体定義
//------------------------------------------------------------------
typedef struct {
	int     	screen;
	GF_BGL_INI	*bgl;
	TCB_PTR 	tcb;
	u16         *panel_trg;
	FIELDSYS_WORK    *fsys;

	int			now_select;

	CLACT_SET_PTR 			clactSet;								// セルアクターセット
	CLACT_U_EASYRENDER_DATA	renddata;								// 簡易レンダーデータ
	CLACT_U_RES_MANAGER_PTR	resMan[CLACT_RESOURCE_TYPE_NUM];				// リソースマネージャ
	CLACT_U_RES_OBJ_PTR 	resObjTbl[CLACT_RESOURCE_CHARA_NUM][CLACT_RESOURCE_TYPE_NUM];		// リソースオブジェテーブル
	CLACT_HEADER			clActHeader_s[CLACT_RESOURCE_CHARA_NUM];// セルアクターヘッダー
	CLACT_WORK_PTR			MenuActWork[FMENU_OAM_MAX];				// セルアクターワークポインタ配列

	GF_BGL_BMPWIN			AButtonWin;								// Aボタンの説明文章
	GF_BGL_BMPWIN			XButtonWin;								// Xボタンの説明文賞

	GF_BGL_BMPWIN			ExplainBmp[MENU_EXPLAIN_NUM];			// アイコンの説明文章

	MENU_EXIST_TBL			exist_tbl[MENU_ICON_NUM];				// メニュー項目の有効フラグ

	MSGDATA_MANAGER 		*msgman;
	WORDSET					*WordSet;								// メッセージ展開用ワークマネージャー

	STRBUF					*ActionStr[ACTION_STRING_MAX];			// Aボタンでできる事文字列
	STRBUF					*XButtonStr[2];							// Xメニュー

	u16						icon_pal[32];							// メニューアイコンのカラー切り替え用

	u8						old_shoes_flag;							// ダッシュシューズアイコンの表示状態保存
	int						old_front_action;						// 一歩先でできる事
	u8						old_appear_flag[FLD_APPEAR_MAX];		// メインメニューのアイコンの表示状態を保存
	// ↑ existと統合して良いと思う。ただし末尾にシューズのフラグがあるのが問題 @@@

	u32						b_KeyButtonEnable : 1;					// 操作系ボタンの有効無効
	u32						menu_mode : 4;							// MENU_MODE 保持用
	u32						menu_enter : 1;							// メニューを選択した
	u32						decide_shortcut : 2;					// ショートカットを選択した
	u32						padding : 24;

	PHONE_WORK				wkPhone;

}BEFORE_POKETCH_WORK;


//==================================================================
// メニューリスト データテーブル
//==================================================================
// ※ここでいうメニューリストは左側にある「Xメニュ−」の事を指します。

#define ELEM_CGX_HOOK_MUSHI_POKE (0xffff) // 項目を虫ポケモン（ポケアイコン）でフックする場合はコレを指定

//--------------------------------------------------------------
/// 項目ごとのデータ
//==============================================================
typedef struct {
	u16 cgr_idx;
	u16 msg_idx : 15;
	u16 b_exist : 1;
} MENU_LIST_ELEM;

//--------------------------------------------------------------
///	項目ID
//==============================================================
enum {
	MENU_LIST_ELEM_ID_ZUKAN = 0,
	MENU_LIST_ELEM_ID_POKEMON,
	MENU_LIST_ELEM_ID_BAG,
	MENU_LIST_ELEM_ID_POKEGEAR,
	MENU_LIST_ELEM_ID_TCARD,
	MENU_LIST_ELEM_ID_REPORT,
	MENU_LIST_ELEM_ID_CONFIG,
	// ↑順番固定 FLD_APPEAR_XXX とあわせてある
	MENU_LIST_ELEM_ID_RETIRE,		///< リタイア
	MENU_LIST_ELEM_ID_SAFARI_BALL,	///< サファリ：残りボール個数
	MENU_LIST_ELEM_ID_PARK_BALL,	///< サファリ：残りボール個数
	MENU_LIST_ELEM_ID_MUSHI_BALL,	///< 虫取り：残りボール個数
	MENU_LIST_ELEM_ID_CHAT,			///< ユニオン：チャット
	MENU_LIST_ELEM_ID_LOG,			///< ユニオン：ログ
	MENU_LIST_ELEM_ID_MAX,
	MENU_LIST_ELEM_ID_NULL = MENU_LIST_ELEM_ID_MAX,
};

//--------------------------------------------------------------
///	項目テーブル
//==============================================================
static const MENU_LIST_ELEM c_MenuListElem[ MENU_LIST_ELEM_ID_MAX ] = {
	// 図鑑
	{
		NARC_poketch_oam001_lz_ncgr, msg_menu_00, 1,
	},
	// ポケモン
	{
		NARC_poketch_oam002_lz_ncgr, msg_menu_01, 1,
	},
	// バッグ
	{
		NARC_poketch_oam003a_lz_ncgr, msg_menu_02, 1,
	},
	// ポケギア
	{
		NARC_poketch_oam004_lz_ncgr, msg_menu_14, 1,
	},
	// トレーナーカード
	{
		NARC_poketch_oam005_lz_ncgr, msg_menu_03, 1,
	},
	// レポート
	{
		NARC_poketch_oam006_lz_ncgr, msg_menu_04, 1,
	},
	// せってい
	{
		NARC_poketch_oam007_lz_ncgr, msg_menu_05, 1,
	},
	// リタイア
	{
		NARC_poketch_oam008_lz_ncgr, msg_menu_08, 1,
	},
	// サファリボール
	{
		// CGXはダミー
		NARC_poketch_oam001_lz_ncgr, msg_menu_32, 0,
	},
	// パークボール
	{
		// CGXはダミー
		NARC_poketch_oam001_lz_ncgr, msg_menu_32, 0,
	},
	// コンペボール
	{
		ELEM_CGX_HOOK_MUSHI_POKE, msg_menu_32, 0,
	},
	// ユニオン：チャット
	{
		NARC_poketch_oam009_lz_ncgr, msg_menu_34, 1,
	},
	// ユニオン：ログ
	{
		NARC_poketch_oam010_lz_ncgr, msg_menu_35, 1,
	},
};

//--------------------------------------------------------------
///	モード毎の項目テーブル
//==============================================================
// exist_tblが7つまでしかないので、8つ目の文字列は ExplainStringXXX 系の関数での初期化・描画・開放が行なわれない。
// 保守性の面から考えるとメニュー項目に関連するものは一元管理するべきだが、
// 入れバグをする危険性を下げるため、
// 今回は、8つ目の項目の文字列をモード毎の例外処理を行なう _exception_xxx 系の関数で描画することにした。
// by hosaka genya 09.06.21
static const u8 c_MenuListElemIdxTbl[ MENU_MODE_MAX ][ MENU_MAX ] = {
	// 通常
	{
		MENU_LIST_ELEM_ID_ZUKAN,
		MENU_LIST_ELEM_ID_POKEMON,
		MENU_LIST_ELEM_ID_BAG,
		MENU_LIST_ELEM_ID_POKEGEAR,
		MENU_LIST_ELEM_ID_TCARD,
		MENU_LIST_ELEM_ID_REPORT,
		MENU_LIST_ELEM_ID_CONFIG,
		MENU_LIST_ELEM_ID_NULL,
	},
	// サファリ
	{
		MENU_LIST_ELEM_ID_RETIRE,
		MENU_LIST_ELEM_ID_ZUKAN,
		MENU_LIST_ELEM_ID_POKEMON,
		MENU_LIST_ELEM_ID_BAG,
		MENU_LIST_ELEM_ID_POKEGEAR,
		MENU_LIST_ELEM_ID_TCARD,
		MENU_LIST_ELEM_ID_CONFIG,
		MENU_LIST_ELEM_ID_SAFARI_BALL,
	},
	// 虫取り
	{
		MENU_LIST_ELEM_ID_RETIRE,
		MENU_LIST_ELEM_ID_ZUKAN,
		MENU_LIST_ELEM_ID_POKEMON,
		MENU_LIST_ELEM_ID_POKEGEAR,
		MENU_LIST_ELEM_ID_TCARD,
		MENU_LIST_ELEM_ID_CONFIG,
		MENU_LIST_ELEM_ID_MUSHI_BALL,
		MENU_LIST_ELEM_ID_NULL, // ポケモンは FMENU_OAM_POS_7 をフックして例外表示(VRAMメモリ削減のため)
	},
	// パルパーク
	{
		MENU_LIST_ELEM_ID_RETIRE,
		MENU_LIST_ELEM_ID_ZUKAN,
		MENU_LIST_ELEM_ID_POKEMON,
		MENU_LIST_ELEM_ID_POKEGEAR,
		MENU_LIST_ELEM_ID_TCARD,
		MENU_LIST_ELEM_ID_CONFIG,
		MENU_LIST_ELEM_ID_PARK_BALL,
		MENU_LIST_ELEM_ID_NULL,
	},
	// ユニオンルーム
	{
		MENU_LIST_ELEM_ID_CHAT,
		MENU_LIST_ELEM_ID_ZUKAN,
		MENU_LIST_ELEM_ID_POKEMON,
		MENU_LIST_ELEM_ID_BAG,
		MENU_LIST_ELEM_ID_LOG,
		MENU_LIST_ELEM_ID_TCARD,
		MENU_LIST_ELEM_ID_CONFIG,
		MENU_LIST_ELEM_ID_NULL,
	},
	// コロシアム
	{
		MENU_LIST_ELEM_ID_POKEMON,
		MENU_LIST_ELEM_ID_BAG,
		MENU_LIST_ELEM_ID_TCARD,
		MENU_LIST_ELEM_ID_CONFIG,
		MENU_LIST_ELEM_ID_NULL,
		MENU_LIST_ELEM_ID_NULL,
		MENU_LIST_ELEM_ID_NULL,
		MENU_LIST_ELEM_ID_NULL,
	},
	// バトルタワーサロン
	{
		MENU_LIST_ELEM_ID_POKEMON,
		MENU_LIST_ELEM_ID_TCARD,
		MENU_LIST_ELEM_ID_CONFIG,
		MENU_LIST_ELEM_ID_NULL,
		MENU_LIST_ELEM_ID_NULL,
		MENU_LIST_ELEM_ID_NULL,
		MENU_LIST_ELEM_ID_NULL,
		MENU_LIST_ELEM_ID_NULL,
	},
};

//------------------------------------------------------------------
/// プロトタイプ宣言
//------------------------------------------------------------------

static void _before_poketch_task( TCB_PTR tcb, void *wk );

static void _dash_func( BEFORE_POKETCH_WORK *bpw, int tp_hit );
static void _dash_shoes_switch( BEFORE_POKETCH_WORK *bpw );
static void _dash_shoes_view_change( BEFORE_POKETCH_WORK *bpw, int flag );
static  int _dash_icon_onoff( BEFORE_POKETCH_WORK *bpw );
static void _decide_func( BEFORE_POKETCH_WORK *bpw, int tp_cont );
static int _get_front_action( BEFORE_POKETCH_WORK* bpw );
static void AButtonStringPut( BEFORE_POKETCH_WORK *bpw, int action );
static void Button_FlashString( BEFORE_POKETCH_WORK* bpw );
static void Button_SetEnable( BEFORE_POKETCH_WORK *bpw, BOOL b_Enable );
static BOOL SubLcdMenu_ReInit( BEFORE_POKETCH_WORK* bpw );
static void SubLcdMenu_On( BEFORE_POKETCH_WORK* bpw );
static void SubLcdMenu_Off( BEFORE_POKETCH_WORK* bpw );
static void SubLcdMenu_Proc( BEFORE_POKETCH_WORK* bpw );
static void SubLcdMenu_Close( BEFORE_POKETCH_WORK* bpw );
static BOOL CheckPassive( FIELDSYS_WORK* fsys );
static void Passive_Set( BEFORE_POKETCH_WORK* bpw, BOOL b_Passive );
static void _icon_shortcut_set_draw( BEFORE_POKETCH_WORK* bpw, BOOL b_Enable );
static   u8 _menuicon_allflag_get( u8 flag[], int num);
static void _menu_icon_appear_init( BEFORE_POKETCH_WORK *wk );
static void _menu_icon_appear_func( BEFORE_POKETCH_WORK *bpw );
// static void IconNamePut( BEFORE_POKETCH_WORK *bpw, int pos, int type, STRBUF *strbuf );

static void _before_poketch_bg_set( GF_BGL_INI *bgl, int patern, GF_BGL_BMPWIN *AButtonWin,  GF_BGL_BMPWIN *XButtonWin, GF_BGL_BMPWIN *ExplainBmp );

static void InitCellActor(BEFORE_POKETCH_WORK *wk);
static void ClactResouceSet( FIELDSYS_WORK* fsys, CLACT_U_RES_MANAGER_PTR* resMan, CLACT_U_RES_OBJ_PTR* resObjTbl, int no, int resNo, int sex, MYITEM *myitem, int menu_mode );
static void SetCellActor(BEFORE_POKETCH_WORK *wk);

static int NextCursorSearch(int pos, int arrow, MENU_EXIST_TBL exist[]);
static void _pal_trans( BEFORE_POKETCH_WORK *bpw, int target );
static void MenuControl( BEFORE_POKETCH_WORK *bpw );
static void HighLightOamInit( CLACT_WORK_PTR ActWork[] );
static void HighLightOamFunc( CLACT_WORK_PTR ActWork[], int now  );
static int TouchControl( BEFORE_POKETCH_WORK *bpw );
static void IconWinWrite( GF_BGL_BMPWIN *MenuBmp, int flag );
static void MenuStringDraw( GF_BGL_BMPWIN *MenuBmp, STRBUF *string, int type );
static void MenuStringSet( BEFORE_POKETCH_WORK *bpw, int flag );
static void MenuStringRelase( BEFORE_POKETCH_WORK *bpw );

static void ExplainStringAppear( BEFORE_POKETCH_WORK *wk );
static void ExplainStringDraw( BEFORE_POKETCH_WORK *wk );

static BOOL CheckTalking( FIELDSYS_WORK* fsys );
static u8 CheckMenuMode( FIELDSYS_WORK* fsys );
static BOOL CheckShortCutEnable( BEFORE_POKETCH_WORK* bpw );

static BOOL _player_shoes_check( BEFORE_POKETCH_WORK *wk );

static void Phone_Init( PHONE_WORK* wk, BEFORE_POKETCH_WORK* bpw );
static void Phone_Proc( PHONE_WORK* wk );
static void Phone_Close( PHONE_WORK* wk );

static void MenuList_PrintException( BEFORE_POKETCH_WORK* bpw );
static void MenuList_SetExist( BEFORE_POKETCH_WORK* bpw );

static int CalcPosIndexToMenuIndex( BEFORE_POKETCH_WORK* bpw, int pos_idx );
static int CalcMenuIndexToPosIndex( BEFORE_POKETCH_WORK* bpw, int menu_idx );
static void CheckSortMenuIndex( BEFORE_POKETCH_WORK* bpw );
static void MagiconFunc(void);
static void NotMagiconFunc1(void);
static void NotMagiconFunc2(void);

#if 0
static BOOL _zukan_event_check( BEFORE_POKETCH_WORK *wk );
static BOOL _first_poke_check( BEFORE_POKETCH_WORK *wk );
static BOOL _pokegear_event_check( BEFORE_POKETCH_WORK *wk );
#endif

//static void menu_obj_test( BEFORE_POKETCH_WORK *wk );
//static void menu_bg_test( BEFORE_POKETCH_WORK *wk );


//==================================================================================================
/**
 *
 *	外部公開関数
 *
 */
//==================================================================================================

//------------------------------------------------------------------
/**
 * ポケッチ取得以前の画面構築
 *
 * @param   none
 *
 */
//------------------------------------------------------------------
TCB_PTR BeforePoketchInit( GF_BGL_INI* bgl, u16 *sub_panel_trg, FIELDSYS_WORK *fsys, void *work )
{
	TCB_PTR       tcb;

	static const GF_BGL_BGCNT_HEADER header[] = {
		{
			0, 0, 0x800, 0,	// scrX, scrY, scrbufSize, scrbufofs,
			GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0x6800, GX_BG_CHARBASE_0x00000,
			GX_BG_EXTPLTT_01, 2, 0, 0, FALSE	// pal, pri, areaover, dmy, mosaic
		},
		{
			0, 0, 0x800, 0,	// scrX, scrY, scrbufSize, scrbufofs,
			GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0x7000, GX_BG_CHARBASE_0x00000,
			GX_BG_EXTPLTT_01, 0, 0, 0, FALSE	// pal, pri, areaover, dmy, mosaic

		},
//		{
//			0, 0, 0x800, 0,	// scrX, scrY, scrbufSize, scrbufofs,
//			GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
//			GX_BG_SCRBASE_0x7800, GX_BG_CHARBASE_0x04000,
//			GX_BG_EXTPLTT_01, 1, 0, 0, FALSE	// pal, pri, areaover, dmy, mosaic
//
//		},
	};

	HOSAKA_PRINT("BPW init sublcd_menu_on = %d\n", fsys->sublcd_menu_on);

	// 異様にデカいがポケッチの合計と同じにしておく
	sys_CreateHeap( HEAPID_BASE_APP, HEAPID_SUBLCD_MENU,  0x18000+0xd00 );

	// BG 設定
	GXS_SetGraphicsMode(GX_BGMODE_0);

	GX_SetBankForSubBG(GX_VRAM_SUB_BG_32_H);
	GX_SetBankForSubOBJ(GX_VRAM_SUB_OBJ_16_I);
	GXS_SetOBJVRamModeChar( GX_OBJVRAMMODE_CHAR_1D_32K );
	GF_BGL_BGControlSet( bgl, GF_BGL_FRAME0_S, &header[0], GF_BGL_MODE_TEXT );
	GF_BGL_BGControlSet( bgl, GF_BGL_FRAME1_S, &header[1], GF_BGL_MODE_TEXT );

	{
		BEFORE_POKETCH_WORK *bpw;
		int i;

		tcb             = PMDS_taskAdd(_before_poketch_task, sizeof(BEFORE_POKETCH_WORK), 10, HEAPID_SUBLCD_MENU);
		bpw             = TCB_GetWork(tcb);
		bpw->tcb        = tcb;
		bpw->screen     = 0;
		bpw->bgl        = bgl;
		bpw->panel_trg  = sub_panel_trg;
		bpw->fsys       = fsys;
		bpw->menu_mode  = CheckMenuMode( bpw->fsys );
		bpw->menu_enter = 0;

		HOSAKA_PRINT("menu_mode:%d\n", bpw->menu_mode);

#if 0
//#ifdef DEBUG_ONLY_FOR_genya_hosaka
		if( bpw->menu_mode == MENU_MODE_MUSHITORI )
		{
			// 画面遷移時にデバッグボタンを押し続けていればコクーンを捕獲したことにする(ヒープでアサートが出る)
			if( sys.cont & PAD_BUTTON_DEBUG )
			{
				FLD_MUSHITORI_WORK* mushi_wk;
				mushi_wk = MushitoriSysSt_GetWorkPointer( fsys );
				if( mushi_wk )
				{
					mushi_wk->get_f = 1;
					mushi_wk->fld_pp = PokeParty_GetMemberPointer( mushi_wk->party_s, 1 );
					PokeParaSet( mushi_wk->fld_pp, MONSNO_KOKUUN, 10, POW_RND, RND_NO_SET, 0, ID_NO_SET, 0 );
				}
			}
		}
#endif

		// BG転送
		_before_poketch_bg_set( bgl, bpw->screen, &bpw->AButtonWin, &bpw->XButtonWin, bpw->ExplainBmp );

		// タッチフォント読み込み
		FontProc_LoadFont(FONT_TOUCH,HEAPID_SUBLCD_MENU);

		// メッセージマネージャ初期化
		// 文字列マネージャー初期化
		bpw->WordSet = WORDSET_Create( HEAPID_SUBLCD_MENU );
		bpw->msgman  = MSGMAN_Create( MSGMAN_TYPE_NORMAL, ARC_MSG, NARC_msg_fieldmenu_dat, HEAPID_SUBLCD_MENU );

		MenuList_SetExist( bpw );

		bpw->now_select = CalcMenuIndexToPosIndex(bpw, fsys->sublcd_menu_select);

		// 無効な場所を選んでいたら頭から有効箇所を検索
		CheckSortMenuIndex( bpw );

		OS_TPrintf( "menu_pos:%d sublcd_pos:%d \n", bpw->now_select, bpw->fsys->sublcd_menu_select);

		// OBJキャラ、パレットマネージャー初期化はfieldmap.cで行っています
		// CellActorシステム初期化
		InitCellActor( bpw );

		// CellActro表示登録
		SetCellActor( bpw );

		// メニュー文字列取得と初期位置の文字描画
		MenuStringSet( bpw, bpw->fsys->sublcd_menu_on );

		// Aボタン文字列描画（センタリング対応）
		GF_STR_PrintColor(	&bpw->AButtonWin, FONT_TOUCH, bpw->ActionStr[1],
					0, 0,
					MSG_ALLPUT,	GF_PRINTCOLOR_MAKE(0xf,1,0), NULL );

		// Xメニュー文字列描画（センタリング対応）
		GF_STR_PrintColor(	&bpw->XButtonWin, FONT_SYSTEM, bpw->XButtonStr[0],
					0, 0,
					MSG_NO_PUT,	GF_PRINTCOLOR_MAKE(0xf,1,0), NULL );

		// メニュー文字列描画(メモリ内で）
		ExplainStringDraw( bpw );

		// メニュー文字列表示判定
		ExplainStringAppear( bpw );

		// アクションボタンを有効に
		Button_SetEnable( bpw, 1 );

		// モード毎の例外表示
		MenuList_PrintException( bpw );

		// 電話着信モジュール初期化
		Phone_Init( &bpw->wkPhone, bpw );

		HOSAKA_PRINT("BPW reinit sublcd_menu_on = %d\n", fsys->sublcd_menu_on);

		// 画面遷移時のキー状態によってパッシブロック判定
		if( KeyTouchStatus_CheckTouchOrKey( &fsys->KeyTouchStatus ) == APP_END_KEY )
		{
			fsys->sublcd_menu_lock_passive = 0;
			OS_TPrintf("BeforePoketchInit:: APP_END_KEY \n");
		}
		else
		{
			if( FieldEvent_Check( fsys ) == FALSE ){
				fsys->sublcd_menu_lock_passive = 1;
			}
			OS_TPrintf("BeforePoketchInit:: APP_END_TOUCH \n");
		}

		// 復帰判定
		if( SubLcdMenu_ReInit( bpw ) == FALSE )
		{
			return tcb;// フィールド復帰を促す（初期化を飛ばす）
		}

		// パッシブ状態初期化
//		Passive_Set( bpw, TRUE );

		// 初期化
		SubLcdMenu_Proc( bpw );

		// セルアクターを描画しておく
		CLACT_Draw( bpw->clactSet );
	}


	// 表示系レジスタ 初期化
	GXS_SetVisibleWnd(GX_WNDMASK_NONE);
//	GXS_SetVisiblePlane(GX_PLANEMASK_BG0|GX_PLANEMASK_BG1);
	GF_Disp_GXS_VisibleControl(GX_PLANEMASK_BG0, VISIBLE_ON);	//BG0面ON
	GF_Disp_GXS_VisibleControl(GX_PLANEMASK_BG1, VISIBLE_ON);	//BG1面ON
	GF_Disp_GXS_VisibleControl(GX_PLANEMASK_BG2, VISIBLE_OFF);	//BG2面OFF
	GF_Disp_GXS_VisibleControl(GX_PLANEMASK_BG3, VISIBLE_OFF);	//BG3面OFF
	GF_Disp_GXS_VisibleControl(GX_PLANEMASK_OBJ, VISIBLE_ON);	//OBJ面ON

	return tcb;
}

FS_EXTERN_OVERLAY(amprotect);

//==============================================================================
/**
 * @brief   終了リクエスト
 *
 * @param   bgl
 * @param   tcb
 *
 * @retval  none
 */
//==============================================================================
void BeforePoketchQuitReq( GF_BGL_INI* bgl,  TCB_PTR tcb )
{
	int i;

	BEFORE_POKETCH_WORK *bpw = TCB_GetWork(tcb);

	OS_Printf("tcb=%08x\n",tcb);

	// ---------------------------------------------
#if MAGICON_CHECK

    FS_LoadOverlay( MI_PROCESSOR_ARM9, FS_OVERLAY_ID(amprotect) );

	if (AM_IsMagiconA1(MagiconFunc)) {
		sys_AllocMemoryLo( HEAPID_BASE_APP, 1000 );
    }
#endif
	// ---------------------------------------------

	// 電話モジュール削除
	Phone_Close( &bpw->wkPhone );

	// メッセージマネージャ削除
	// 文字列マネージャー削除
	MSGMAN_Delete(  bpw->msgman  );
	WORDSET_Delete( bpw->WordSet );

	// セルアクターリソース解放
	// キャラ転送マネージャー破棄
	for(i=0;i<CLACT_RESOURCE_CHARA_NUM;i++){
		CLACT_U_CharManagerDelete( bpw->resObjTbl[i][CLACT_U_CHAR_RES] );
	}

	// パレット転送マネージャー破棄
	for(i=0;i<CLACT_RESOURCE_CHARA_NUM;i++){
		CLACT_U_PlttManagerDelete( bpw->resObjTbl[i][CLACT_U_PLTT_RES] );
	}

	// キャラ・パレット・セル・セルアニメのリソースマネージャー破棄
	for(i=0;i<CLACT_RESOURCE_TYPE_NUM;i++){
		CLACT_U_ResManagerDelete(bpw->resMan[i]);
	}

	// ---------------------------------------------
#if MAGICON_CHECK
    if (!AM_IsNotMagiconA2(NotMagiconFunc1)) {
		sys_AllocMemoryLo( HEAPID_BASE_APP, 1000 );
    }
#endif
	// ---------------------------------------------


	// セルアクターセット破棄
	CLACT_DestSet(bpw->clactSet);

	// メニュー文字列のBMPWIN確保
	for(i=0;i<MENU_EXPLAIN_NUM;i++){
		GF_BGL_BmpWinDel( &bpw->ExplainBmp[i] );
	}

	GF_BGL_BmpWinDel( &bpw->XButtonWin );
	GF_BGL_BmpWinDel( &bpw->AButtonWin );

	// メニュー文字列解放
	MenuStringRelase( bpw );

	//タッチフォントアンロード
	FontProc_UnloadFont(FONT_TOUCH);

	PMDS_taskDel( tcb );

	GF_BGL_BGControlExit( bgl, GF_BGL_FRAME1_S );
	GF_BGL_BGControlExit( bgl, GF_BGL_FRAME0_S );
	sys_DeleteHeap( HEAPID_SUBLCD_MENU );



#if MAGICON_CHECK
    if ((!AM_IsNotMagiconA3(NotMagiconFunc2))) {
		sys_AllocMemoryLo( HEAPID_BASE_APP, 1000 );
    }
	FS_UnloadOverlay(MI_PROCESSOR_ARM9, FS_OVERLAY_ID(amprotect));
#endif
	// ---------------------------------------------

}

//==============================================================================
/**
 * @brief   終了待ち（即終了）
 *
 * @param   bgl
 *
 * @retval  BOOL
 */
//==============================================================================
BOOL BeforePoketchQuitWait( GF_BGL_INI* bgl )
{
	return TRUE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	フィールドメニュー選択フラグ設定
 *
 *	@param	TCB_PTR tcb
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void FieldMenuSelectFlagSet( TCB_PTR tcb )
{
	BEFORE_POKETCH_WORK * bpw;

	bpw = TCB_GetWork(tcb);

	GF_ASSERT(bpw);

	bpw->menu_enter = 1;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ショートカット起動フラグ設定
 *
 *	@param	TCB_PTR tcb
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void FieldMenuSelectShortcutFlagSet( TCB_PTR tcb, int shortcutID )
{
	BEFORE_POKETCH_WORK * bpw;

	bpw = TCB_GetWork(tcb);

	GF_ASSERT(bpw);
	GF_ASSERT( shortcutID==1 || shortcutID==2 );

	bpw->decide_shortcut = shortcutID;
}

//==================================================================================================
/**
 *
 *	static関数
 *
 */
//==================================================================================================

#ifdef DEBUG_PHONE
// でんわデバッグ用func
static void _debug_phone( BEFORE_POKETCH_WORK* bpw )
{
	if(sys.trg & PAD_BUTTON_SELECT){
		FldPMTel_CallupFlagSet(bpw->wkPhone.pmtel);
	}
	if(sys.trg & PAD_BUTTON_START){
		FldPMTel_CallupFlagReset(bpw->wkPhone.pmtel);
		CLACT_AnmChg( bpw->MenuActWork[FMENU_OAM_POKEGEAR], 0 );
	}
}
#endif

//------------------------------------------------------------------
/**
 * @brief   ポケッチ取得前アプリタスク
 *
 * @param   tcb
 * @param   wk
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _before_poketch_task( TCB_PTR tcb, void *wk )
{
	// タッチ判定座標定義配列追加分
	static const RECT_HIT_TBL ExtraKeyHitTbl[]={
		{ 86,134,184,252,},		// Ｂボタン
		{144,188,168,255,},		// Ａボタン
		{RECT_HIT_END,0,0,0},
	};

	int i;
	BEFORE_POKETCH_WORK *bpw = (BEFORE_POKETCH_WORK *)wk;
	BOOL b_Passive = CheckPassive( bpw->fsys );
	BOOL b_MoveControl = FieldMap_CheckHeroMove( bpw->fsys );

#ifdef DEBUG_PHONE
	_debug_phone(wk);
#endif

//	HOSAKA_PRINT("lock_passive=%d ",bpw->fsys->sublcd_menu_lock_passive);
//	HOSAKA_PRINT("menu::CheckHeroMove=%d passive:%d \n",b_MoveControl, b_Passive);
//	HOSAKA_PRINT("sublcd_menu_select:%d\n", bpw->fsys->sublcd_menu_select);
//	HOSAKA_PRINT("now_select:%d\n", bpw->now_select);
//	HOSAKA_PRINT("SpScriptCheck:%d \n", SpScriptCheck(bpw->fsys) );

	//----------------------------------------------------------
	// パッシブ処理
	//----------------------------------------------------------
	if( bpw->fsys->sublcd_menu_lock_passive )
	{
		// 動作可能状態になったらパッシブロックOFF
		if( b_MoveControl && WIPE_SYS_EndCheck() )
		{
//			Passive_Set( bpw, b_Passive );
			bpw->fsys->sublcd_menu_lock_passive = 0;
		}
		else
		// パッシブロック処理
		{
			G2S_BlendNone();
		}
	}
	else
	{
		Passive_Set( bpw, b_Passive );
	}

	// === 選択アニメ ===
	// メニュー選択時に
	if( bpw->menu_enter )
	{
		// 選択アニメ
		CLACT_AnmChgCheck( bpw->MenuActWork[ bpw->now_select ], 2 );
	}

	// ショートカット 選択アニメ
	if( bpw->decide_shortcut == 1 )
	{
		CLACT_AnmChg( bpw->MenuActWork[ FMENU_OAM_SHORTCUT1 ], 2 );
		bpw->decide_shortcut = 0; // 初期化
	}
	else if( bpw->decide_shortcut == 2 )
	{
		CLACT_AnmChg( bpw->MenuActWork[ FMENU_OAM_SHORTCUT2 ], 2 );
		bpw->decide_shortcut = 0; // 初期化
	}

	// イベント中判定
	if( FieldEvent_Check( bpw->fsys ) )
	{
		// メインメニュー駆動 (Xメニュー)
		SubLcdMenu_Proc( bpw );
	}
	else
	{
		// 閉じた後処理
		if( bpw->fsys->sublcd_menu_on == SUBLCD_MENU_ON )
		{
			SubLcdMenu_Close( bpw );
			bpw->fsys->sublcd_menu_on = SUBLCD_MENU_OFF;
		}

		// 主人公が動作可能ならアクションボタン文字列更新
		if( b_MoveControl )
		{
			Button_FlashString( bpw );
		}

		if( b_Passive == FALSE )
		{
			// タッチ判定
			TouchControl(bpw);
		}
	}

	// タッチパネルのA・ダッシュボタン判定
	{
		int tp_cont = GF_TP_RectHitCont(ExtraKeyHitTbl);
		int tp_hit  = GF_TP_RectHitTrg(ExtraKeyHitTbl);

		// Aボタンチェック
		_decide_func( bpw, tp_cont );

		if( bpw->b_KeyButtonEnable )
		{
			int shoesflag;

			// ダッシュシューズが使えないなら非表示
			shoesflag= _dash_icon_onoff( bpw );

			// 非パッシブ時のみチェック
			if( shoesflag && b_Passive == FALSE )
			{
				// ダッシュモードチェック
				_dash_func( bpw, tp_hit );
			}
		}
	}

#if 0
//#ifdef DEBUG_ONLY_FOR_genya_hosaka
	if( sys.trg & PAD_BUTTON_DEBUG )
	{
		FIELDSYS_WORK* fsys = bpw->fsys;
		u32	o_deposit,n_deposit;
		PMTEL_SAVE* tel_sv = SaveData_GetPMTelSave(fsys->savedata);

		//現在の貯金金額
		o_deposit = PMTelSv_DepositControl(tel_sv, PMTEL_DEPOSIT_GET, 0);
		n_deposit = o_deposit;

		//使い込みチェック
		if(FldPMTel_MatherEmbezzlementCheck(tel_sv,n_deposit,o_deposit))
		{
			//使い込みが発生したら電話予約
			FldPMTel_IncomingReservation(FldPMTel_PointerGet(fsys),PMTEL_RESERVE_MAMA_EMBEZZLEMENT,TRUE);
		}
	}
#endif

	// 電話着信処理
	Phone_Proc( &bpw->wkPhone );

	// セルアクター描画
	CLACT_Draw( bpw->clactSet );
}

//----------------------------------------------------------------------------------
/**
 * ダッシュシューズとその下のボタンの見え方を変更する
 *
 * @param   bpw
 * @param   flag	0:ダッシュOFF	1:ダッシュON
 */
//----------------------------------------------------------------------------------
static void _dash_shoes_view_change( BEFORE_POKETCH_WORK *bpw, int flag )
{
	CLACT_AnmChg( bpw->MenuActWork[FMENU_OAM_DASH_GEAR], 11-flag*4);
	CLACT_AnmChg( bpw->MenuActWork[FMENU_OAM_B_BUTTON],  3+flag );

}

//------------------------------------------------------------------
/**
 * @brief   タッチダッシュボタンチェック
 *
 * @param   bpw
 * @param   cont
 * @param   trg
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _dash_func( BEFORE_POKETCH_WORK *bpw, int tp_hit )
{

	// ダッシュボタントリガチェック
	if(tp_hit==0){
		// ダッシュモード切替
		PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( bpw->fsys );
		BOOL flag = Player_DashBitGet( jiki );
		// くつアイコンのカラー切り替え
		OS_Printf("flag=%d\n", flag);
		// フラグ反転
		flag ^= 1;
		_dash_shoes_view_change( bpw, flag );
		Player_DashBitSet( jiki, flag );
	}

}

//------------------------------------------------------------------
/**
 * @brief   ダッシュ状態によってくつアイコンのパターンを変える
 *
 * @param   bpw
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _dash_shoes_switch( BEFORE_POKETCH_WORK *bpw )
{

	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( bpw->fsys );
	int flag = Player_DashBitGet( jiki );

	_dash_shoes_view_change( bpw, flag );
}

//------------------------------------------------------------------
/**
 * @brief   ダッシュアイコンをONOFFする
 *
 * @param   bpw
 *
 * @retval  int		1:ダッシュボタン使って良い 0:ダメ
 */
//------------------------------------------------------------------
static int _dash_icon_onoff( BEFORE_POKETCH_WORK *bpw )
{
	// ダッシュシューズは持っているか？
	int shoesflag    = _player_shoes_check( bpw );

	if(	( Player_FormGet(bpw->fsys->player) == HERO_FORM_CYCLE ) ||	// 自転車に乗っているか
		( bpw->fsys->sublcd_menu_on )) {	// メインメニューを開いているか
		shoesflag = 0;
	}

	// ダッシュボタン表示判定
	if(shoesflag){
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_B_BUTTON],  1 );
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_DASH_GEAR], 1 );
	}else{
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_B_BUTTON],  0 );
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_DASH_GEAR], 0 );
	}

	return shoesflag;
}

//------------------------------------------------------------------
/**
 * @brief   タッチAボタンチェック
 *
 * @param   bpw
 * @param   cont
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _decide_func( BEFORE_POKETCH_WORK *bpw, int tp_cont )
{
	enum {
		BTN_ANIME_SEQ_NORMAL = 5,
		BTN_ANIME_SEQ_DOWN = 6,
	};

	int anm_seq = CLACT_AnmGet( bpw->MenuActWork[FMENU_OAM_A_BUTTON] );

	// Aボタンが非表示ならば処理を抜ける
	if( CLACT_GetDrawFlag( bpw->MenuActWork[FMENU_OAM_A_BUTTON] ) == FALSE )
	{
		return;
	}

	// 初回タッチ
	if( tp_cont == 1 && GF_TP_GetTrg() )
	{
		sys.extra_cont = PAD_BUTTON_A;
		CLACT_AnmChg( bpw->MenuActWork[FMENU_OAM_A_BUTTON], BTN_ANIME_SEQ_DOWN );
	}
	// 継続タッチ
	else if( tp_cont == 1 && anm_seq == BTN_ANIME_SEQ_DOWN )
	{
		sys.extra_cont = PAD_BUTTON_A;
	}
	// 非タッチ状態
	else
	{
		CLACT_AnmChg( bpw->MenuActWork[FMENU_OAM_A_BUTTON], BTN_ANIME_SEQ_NORMAL );
	}
}

static const u8 action_switch_tbl[]={1,0,1,3,4};
//-----------------------------------------------------------------------------
/**
 *	@brief	フィールドOBJの状態からアクションIDを取得
 *
 *	@param	FIELDSYS_WORK* fsys
 *
 *	@retval	アクションID（action_switch_tbl のインデックス）
 */
//-----------------------------------------------------------------------------
static int _get_front_action( BEFORE_POKETCH_WORK* bpw )
{
	int front_action;
	FIELDSYS_WORK* fsys = bpw->fsys;

	if( CheckTalking( fsys ) )
	{
		// 強制で「つづける」
		return 4;
	}
	// 主人公が移動できない状態
	else if( FieldMap_CheckHeroMove(fsys) == FALSE )
	{
		// 「つり」チェック
		{
			PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
			FIELD_OBJ_PTR fieldobj = Player_FieldOBJGet( jiki );

			int status = FieldOBJ_DrawStatusGet(fieldobj);
			int code  =  FieldOBJ_OBJCodeGet( fieldobj );

			if( code == FISHINGHERO || code == FISHINGHEROINE ){
				if(status==1){
					return ACTION_FISHING;
				}else{
					return ACTION_CONTINUE;
				}
			}
		}

		// 「つぎへ」以外は現状維持
		if( bpw->old_front_action != 4 )
		{
			return bpw->old_front_action;
		}
	}

	// フィールドOBJからアクションを判定
	front_action = FieldCheck_FrontAction( fsys );

	// 「はなす」アクションなら
	if( front_action == 1 )
	{
		FIELD_OBJ_PTR obj;

		// 目の前のOBJを取得
		SXY_HeroFrontObjGet( fsys, &obj );

		if( FieldSublcd_FrontEventCheck( FieldOBJ_EventIDGet(obj) ) ||
			FieldSublcd_ObjNoTalkCheck( FieldOBJ_OBJCodeGet(obj) ) )
		{
			//「しらべる」アクションにフック
			front_action = 0;
		}
	}

	return front_action;
}

//------------------------------------------------------------------
/**
 * @brief   Aボタン描画
 *
 * @param   bpw
 * @param   action
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void AButtonStringPut( BEFORE_POKETCH_WORK *bpw, int action )
{
	GF_BGL_BmpWinDataFill( &bpw->AButtonWin, 0 );
	GF_STR_PrintColor(	&bpw->AButtonWin, FONT_TOUCH, bpw->ActionStr[action_switch_tbl[action]],
	0, 0, MSG_ALLPUT,	GF_PRINTCOLOR_MAKE(0xf,1,0), NULL );

	// Aボタンのみ有効化（リタイア時のため）
	CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_A_BUTTON],  1 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	アクションボタンの文字列更新
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Button_FlashString( BEFORE_POKETCH_WORK* bpw )
{
	int front_action = _get_front_action( bpw );

	if( bpw->old_front_action!= front_action )
	{
		AButtonStringPut( bpw, front_action );
		bpw->old_front_action = front_action;
	}
}

//------------------------------------------------------------------
/**
 * @brief   ボタン状態・描画設定
 *
 * @param   MenuBmp
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void Button_SetEnable( BEFORE_POKETCH_WORK *bpw, BOOL b_Enable )
{
	if( b_Enable )
	{
		bpw->b_KeyButtonEnable = 1;

		// ダッシュボタンを表示
		_dash_icon_onoff( bpw );
		// ショートカットボタンを表示
		_icon_shortcut_set_draw( bpw, 1 );
		// アクションボタンを表示
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_A_BUTTON],  1 );
	}
	else
	{
		bpw->b_KeyButtonEnable = 0;

		GF_BGL_BmpWinDataFill( &bpw->AButtonWin, 0 );
		GF_BGL_BmpWinOn( &bpw->AButtonWin );

		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_A_BUTTON],  0 );
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_B_BUTTON],  0 );
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_DASH_GEAR], 0 );

		// ショートカットもOFF
		_icon_shortcut_set_draw( bpw, 0 );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	復帰処理
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval	TRUE : 継続, FALSE : 終了
 */
//-----------------------------------------------------------------------------
static BOOL SubLcdMenu_ReInit( BEFORE_POKETCH_WORK* bpw )
{
	FIELDSYS_WORK* fsys;
	u16* panel_trg;

	GF_ASSERT( bpw->panel_trg );

	fsys = bpw->fsys;
	panel_trg = bpw->panel_trg;

	// 下画面メニューにフィールド復帰を促す
	if( fsys->sublcd_menu_on == SUBLCD_MENU_TO_FIELD )
	{
		// キーで終了していた時はパッシブ初期化
		if( KeyTouchStatus_CheckTouchOrKey( &fsys->KeyTouchStatus ) == APP_END_KEY )
		{
			Passive_Set( bpw, TRUE );
		}
		else
		{
			fsys->sublcd_menu_on = SUBLCD_MENU_OFF;
		}
	}
	else
	// フィールド常駐アプリから復帰
	if( fsys->sublcd_menu_on == SUBLCD_MENU_FROM_FIELD )
	{
		// 下画面アプリ終了時にタッチで終了している場合はメニューを開かない
		if(KeyTouchStatus_CheckTouchOrKey( &fsys->KeyTouchStatus )==APP_END_TOUCH)
		{
			// sub_panel_trg に対してポーズを解除通知を出すがメニューは更新しない
			*panel_trg = SUBLCD_TOUCH_OPEN_MENU;
			fsys->sublcd_menu_on = SUBLCD_MENU_OFF;
			fsys->sublcd_menu_lock_passive = 1;
		}else{
			// 下画面アプリがキーで終了している場合
			// 選択中のアイコンのパレットを変える
			_pal_trans( bpw, bpw->now_select );
			fsys->sublcd_menu_on = SUBLCD_MENU_ON_INIT;
		}
	}

	return TRUE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SubLcdMenu_Off( BEFORE_POKETCH_WORK* bpw )
{
	// フィールドマップメインが動作していればアクションボタン文字列を更新
	if(GameSystem_CheckFieldMain( bpw->fsys )==TRUE)
	{
		Button_FlashString( bpw );
	}

	// 通常メニューでしか appear は発動しない
	if(bpw->menu_mode == MENU_MODE_NORMAL)
	{
		// イベント中でメインメニューを開いていない（会話やスクリプトが動作している）
		_menu_icon_appear_func( bpw );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SubLcdMenu_On( BEFORE_POKETCH_WORK* bpw )
{
	GF_ASSERT( bpw->now_select < MENU_ICON_NUM );

	_pal_trans( bpw, bpw->now_select );
	// アクションボタンを非アクティブに
	Button_SetEnable( bpw, 0 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	SubLcdMenu：PROC駆動
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SubLcdMenu_Proc( BEFORE_POKETCH_WORK* bpw )
{
	switch( bpw->fsys->sublcd_menu_on )
	{
	case SUBLCD_MENU_OFF :
		SubLcdMenu_Off( bpw );
		break;

	case SUBLCD_MENU_ON_INIT :
		// fld_menuで sublcd_menu_on がセットされることがあるので、常に監視する必要がある
		SubLcdMenu_On( bpw );
		bpw->fsys->sublcd_menu_on = SUBLCD_MENU_ON;
		break;

	case SUBLCD_MENU_ON :
		if( bpw->fsys->main_mode_flag && WIPE_SYS_EndCheck() )
		{
			// タッチ処理とメニュー処理(タッチ優先）
			if( TouchControl(bpw) )
			{
				MenuControl(bpw);
			}
		}
		break;

	// Init中で復帰処理をするので以下にはならない
	case SUBLCD_MENU_FROM_FIELD :
	case SUBLCD_MENU_TO_FIELD :
	default : GF_ASSERT_MSG( 0, "case over : sublcd_menu_on=%d\n", bpw->fsys->sublcd_menu_on);
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	SubLcdMenu：閉じた時の処理
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SubLcdMenu_Close( BEFORE_POKETCH_WORK* bpw )
{
	int front_action;

	// Aボタン描画文字列変更
	front_action = _get_front_action( bpw );
	AButtonStringPut( bpw, front_action );
//	Button_FlashString( bpw );

	// OBJパレットを全てデフォルトにする
	_pal_trans( bpw, -1 );

//	Phone_Close( &bpw->wkPhone );

	GF_BGL_BmpWinOn( &bpw->AButtonWin );

	// キーボタンをアクティブに
	Button_SetEnable( bpw, 1 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	パッシブ状態か判定
 *
 *	@param	FIELDSYS_WORK* fsys
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static BOOL CheckPassive( FIELDSYS_WORK* fsys )
{
	return(
		WIPE_SYS_EndCheck() == FALSE ||
		fsys->main_mode_flag == FALSE ||
		fsys->sublcd_menu_on ||
		FieldMap_CheckHeroMove( fsys ) == FALSE ||
		CheckTalking( fsys ) ||
		SpScriptCheck( fsys ) ||
		CommIsWaitBattleStart() //BTS4761
	);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	パッシブ処理
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Passive_Set( BEFORE_POKETCH_WORK* bpw, BOOL b_Passive )
{
	if( b_Passive )
	{
#if GS_AFTERMASTER_BTS5422_20090918_FIX
  // コロシアム(通信部屋)
  if( bpw->menu_mode == MENU_MODE_COLOSSEUM && bpw->fsys->sublcd_menu_on == SUBLCD_MENU_OFF )
  {
    // OBJパレットを全てデフォルトにする
    _pal_trans( bpw, -1 );
  }
#endif

    // パッシブ状態
		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_B_BUTTON],  GX_OAM_MODE_XLU );
		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_DASH_GEAR], GX_OAM_MODE_XLU );

		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT1],  GX_OAM_MODE_XLU );
		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT1_BG], GX_OAM_MODE_XLU );
		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT2],  GX_OAM_MODE_XLU );
		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT2_BG], GX_OAM_MODE_XLU );

		// メニューが開かれていた時は
		if( bpw->fsys->sublcd_menu_on ){
			// OAMハイライト処理(カーソルで選択されているものは除く)
			HighLightOamFunc( bpw->MenuActWork, bpw->now_select);
		}else{
			// OAMハイライト処理(全て透明）
			HighLightOamFunc( bpw->MenuActWork, -1 );
		}

		// 虫取り大会 例外処理
		if( bpw->menu_mode == MENU_MODE_MUSHITORI )
		{
			// 虫ポケでフックしている場合はパッシブにならない
			CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_MUSHIPOKE],  GX_OAM_MODE_NORMAL );
		}

		G2S_SetBlendAlpha(	0, GX_BLEND_PLANEMASK_BD|GX_BLEND_PLANEMASK_BG0|GX_BLEND_PLANEMASK_BG1, 0x06, 0x09 );
	}
	else
	{
		// 通常状態
//		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_B_BUTTON],  GX_OAM_MODE_NORMAL );
//		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_DASH_GEAR], GX_OAM_MODE_NORMAL );

//		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT1],  GX_OAM_MODE_NORMAL );
//		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT1_BG], GX_OAM_MODE_NORMAL );
//		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT2],  GX_OAM_MODE_NORMAL );
//		CLACT_ObjModeSet( bpw->MenuActWork[FMENU_OAM_SHORTCUT2_BG], GX_OAM_MODE_NORMAL );

		G2S_BlendNone();
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ショートカットのアイコンを登録状況によってＯＮ／ＯＦＦする
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *	@param	b_Enable	TRUE:登録状況によってON/OFF, FALSE:無条件で非表示
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void _icon_shortcut_set_draw( BEFORE_POKETCH_WORK* bpw, BOOL b_Enable )
{
	// ショートカット無効メニューなら強制的に非表示
	if( CheckShortCutEnable(bpw) == FALSE )
	{
		b_Enable = 0;
	}

	if( b_Enable )
	{
		MYITEM* myitem = SaveData_GetMyItem( bpw->fsys->savedata );
		BOOL exist_1 = (MyItem_CnvButtonItemGet( myitem ) != 0 );
		BOOL exist_2 = (MyItem_CnvButton2ItemGet( myitem ) != 0 );

		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT1],		exist_1 );
		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT1_BG],	exist_1 );
		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT2],		exist_2 );
		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT2_BG],	exist_2 );
	}
	else
	{
		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT1],		0 );
		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT1_BG],	0 );
		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT2],		0 );
		CLACT_SetDrawFlag(  bpw->MenuActWork[FMENU_OAM_SHORTCUT2_BG],	0 );
	}
}

typedef struct{
	u16 oam_no;
	u16 anim;
	u8  bmp_no;
}APPEAR_ICON_DAT;

static const APPEAR_ICON_DAT appear_dat[]={
	{ FMENU_OAM_POS_1,	4, 0, },	// 図鑑
	{ FMENU_OAM_POS_2,	4, 1, },	// モンスターボール
	{ FMENU_OAM_POS_3,	4, 2, },	// バッグ
	{ FMENU_OAM_POS_4,	4, 3, },	// ポケギア
	{ FMENU_OAM_POS_5,	4, 4, },	// カード
	{ FMENU_OAM_POS_6,	4, 5, },	// レポート
	{ FMENU_OAM_POS_7,	4, 6, },	// コンフィグ
};


static u8 _menuicon_allflag_get( u8 flag[], int num)
{
	int i,ret=0;
	for(i=0;i<num;i++){
		ret+=flag[i];
	}
	return ret;
}

//------------------------------------------------------------------
/**
 * @brief   取得フラグを見てメニューアイコンの表示制御を行う
 *
 * @param   wk
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _menu_icon_appear_init( BEFORE_POKETCH_WORK *wk )
{
	int i;

	// メニュー表示初期化
	for( i=0; i<MENU_ICON_NUM; i++ )
	{
		BOOL exist = wk->old_appear_flag[i];

		CLACT_SetDrawFlag( wk->MenuActWork[i], exist );
	}

	// まだダッシュシューズを貰っていないならBボタンパネルを出さない
	wk->old_shoes_flag = 1;
	if(! _player_shoes_check(wk)){
		CLACT_SetDrawFlag( wk->MenuActWork[FMENU_OAM_B_BUTTON], 0 );
		CLACT_SetDrawFlag( wk->MenuActWork[FMENU_OAM_DASH_GEAR], 0 );
		wk->old_shoes_flag=0;
	}
}

//------------------------------------------------------------------
/**
 * @brief   イベント中にフラグが立った際にメインメニューのアイコンを登場させる
 *
 * @param   bpw
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _menu_icon_appear_func( BEFORE_POKETCH_WORK *bpw )
{
	int i,flag,count=0,old_menu=0;

	old_menu = _menuicon_allflag_get( bpw->old_appear_flag, MENU_ICON_NUM );

	count = old_menu;

	// 各アイコンの表示状態を取得してリアルタイムに表示する必要がある場合はアニメ再生
	for(i=0;i<MENU_ICON_NUM;i++){
		flag = FldMenu_ExecuteCheck( bpw->fsys, i);
		// アイコンフラグがイベント中に立った場合はアニメーション開始
		if(flag==1 && bpw->old_appear_flag[i]==0){
			CLACT_SetDrawFlag( bpw->MenuActWork[appear_dat[i].oam_no], 1 );
			CLACT_AnmChg( bpw->MenuActWork[appear_dat[i].oam_no], appear_dat[i].anim );
			GF_BGL_BmpWinOn( &bpw->ExplainBmp[appear_dat[i].bmp_no] );
			bpw->old_appear_flag[i] = 1;
			bpw->exist_tbl[i].exist = 1;
			bpw->fsys->sublcd_menu_lock_passive = 1;
			count++;
		}
	}

	// メニューアイコンが初めて現れた時
	if( count && old_menu == 0 )
	{
		// 「Ｘメニュー」文字列をＯＮにする
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_X_ICON], 1 );
		GF_BGL_BmpWinOn( &bpw->XButtonWin );
	}

	// 項目が増えた場合、メニュー位置をリセット
	if( old_menu != count )
	{
		bpw->fsys->sublcd_menu_select = 0;
		bpw->now_select = CalcMenuIndexToPosIndex( bpw, bpw->fsys->sublcd_menu_select );
		CheckSortMenuIndex( bpw );
	}
		// カーソル位置をバッグにする
//		bpw->now_select = MENU_POS_03;
//		bpw->fsys->sublcd_menu_select = CalcPosIndexToMenuIndex( bpw, bpw->now_select );

	// ダッシュボタンパネル
	flag    = _player_shoes_check( bpw );
	if(flag==1 && bpw->old_shoes_flag==0){
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_B_BUTTON], 1 );
		CLACT_SetDrawFlag( bpw->MenuActWork[FMENU_OAM_DASH_GEAR], 1 );
		CLACT_AnmChg( bpw->MenuActWork[FMENU_OAM_B_BUTTON], 10 );
		bpw->old_shoes_flag = 1;
	}


}

#if 0
//------------------------------------------------------------------
/**
 * @brief   メニューアイコンの名前をBMPWINで表示
 *
 * @param   bpw
 * @param   pos		アイコンの位置
 * @param   type	通常枠か電話枠
 * @param   strbuf	表示する文字列
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void IconNamePut( BEFORE_POKETCH_WORK *bpw, int pos, int type, STRBUF *strbuf )
{
	// 名前表示BMPを登録する位置情報( x, y, flag(0=左寄せ:1=右寄せ))
	static const int MenuNamePos[][3]={
		{  1,  6, 0 },		// ずかん
		{  1, 11, 0 },		// モンスターボール
		{  1, 16, 0 },		// バッグ
		{  9, 18, 0 },		// ポケギア
		{ 11,  6, 0 },		// トレーナーカード
		{ 11, 11, 0 },		// セーブ
		{ 18, 16, 0 },		// コンフィグ
		{ 23,  7, 1 },		// ショートカット１
		{ 28,  4, 1 },		// ショートカット２
	};

	int w = FontProc_GetPrintStrWidth( FONT_SYSTEM, strbuf, 0  );
	int x = MenuNamePos[pos][0];

	// 既に呼びだれているウインドウがある場合は呼ばない
	if(bpw->MenuNameOn){
		return;
	}

	// 文字列表示に使うキャラ数を取得
	w = (w/8)+2;

	// 右寄せ定義の場合を算出
	if(MenuNamePos[pos][2]){
		x = x-w;
	}

	// メニュー説明文字列用BMPWIN確保
	GF_BGL_BmpWinAdd( bpw->bgl, &bpw->MenuBmp, GF_BGL_FRAME1_S,
			x,  MenuNamePos[pos][1],
			w,  MENU_STRING_H,
			MENU_STRING_PAL,  MENU_STRING_VRAM_OFFSET );

	// スクリーンバッファクリア
	//GF_BGL_ScrFill(	bpw->bgl, GF_BGL_FRAME1_S, 0, 0, 0, 31, 24, MENU_STRING_PAL );

	// ウインドウ枠描画
	IconWinWrite( &bpw->MenuBmp, type );

	// 文字列描画
	MenuStringDraw( &bpw->MenuBmp, strbuf, type );

	GF_BGL_BmpWinOn( &bpw->AButtonWin );
//	GF_BGL_BmpWinOn( &bpw->XButtonWin );

	bpw->MenuNameOn = 1;

}

#endif

// テスト用の下画面スクリーンデータ
static const int BeforePoketchBgTable[][3]={
	{
		NARC_poketch_udmenu_bg_nclr,
		NARC_poketch_udmenu_bg01_lz_ncgr,
		NARC_poketch_udmenu_bg01_lz_nscr,
	},
	{
		NARC_poketch_udmenu_bg_nclr,
		NARC_poketch_udmenu_bg01_lz_ncgr,
		NARC_poketch_udmenu_bg01_lz_nscr,
	},
	{
		NARC_poketch_udmenu_bg_nclr,
		NARC_poketch_udmenu_bg01_lz_ncgr,
		NARC_poketch_udmenu_bg01_lz_nscr,
	},

};

static const explain_bmp_xy[ MENU_EXPLAIN_NUM ][2]={
	{ EXPLAIN0_WIN_X, EXPLAIN0_WIN_Y, },
	{ EXPLAIN1_WIN_X, EXPLAIN1_WIN_Y, },
	{ EXPLAIN2_WIN_X, EXPLAIN2_WIN_Y, },
	{ EXPLAIN3_WIN_X, EXPLAIN3_WIN_Y, },
	{ EXPLAIN4_WIN_X, EXPLAIN4_WIN_Y, },
	{ EXPLAIN5_WIN_X, EXPLAIN5_WIN_Y, },
	{ EXPLAIN6_WIN_X, EXPLAIN6_WIN_Y, },
	{ EXPLAIN7_WIN_X, EXPLAIN7_WIN_Y, },
};

//==============================================================================
/**
 * @brief   指定のパレット・キャラ・スクリーンを下画面用に転送
 *
 * @param   bgl
 * @param   patern	0-2:朝・昼・晩を表す
 *
 * @retval  none
 */
//==============================================================================
static void _before_poketch_bg_set( GF_BGL_INI *bgl, int patern, GF_BGL_BMPWIN *AButtonWin,  GF_BGL_BMPWIN *XButtonWin, GF_BGL_BMPWIN *ExplainBmp )
{
	int i;

	// BG0面の転送
	ArcUtil_BgCharSet(ARC_SUBLCDMENU_GRA, BeforePoketchBgTable[patern][1], bgl, GF_BGL_FRAME0_S,
		0, 0, TRUE, HEAPID_POKETCH_APP);
	ArcUtil_ScrnSet(ARC_SUBLCDMENU_GRA, BeforePoketchBgTable[patern][2], bgl, GF_BGL_FRAME0_S,
		0, 0, TRUE, HEAPID_POKETCH_APP);
	ArcUtil_PalSet(ARC_SUBLCDMENU_GRA, BeforePoketchBgTable[patern][0], PALTYPE_SUB_BG,
		0, 0x200, HEAPID_POKETCH_APP);

	// フォントパレット転送
//	SystemFontPaletteLoad( PALTYPE_SUB_BG, MENU_STRING_PAL_OFFSET, HEAPID_POKETCH_APP );

	// Ａボタンで行う動作を表示するBMPWIN
	GF_BGL_BmpWinAdd( bgl, AButtonWin, GF_BGL_FRAME1_S, ABUTTON_WIN_X, ABUTTON_WIN_Y,
						 ABUTTON_WIN_W, ABUTTON_WIN_H, MENU_STRING_PAL,  ABUTTON_VRAM_OFFSET );
	GF_BGL_BmpWinDataFill( AButtonWin, 0 );

	// Xボタンで行う動作を表示するBMPWIN
	GF_BGL_BmpWinAdd( bgl, XButtonWin, GF_BGL_FRAME1_S, XBUTTON_WIN_X, XBUTTON_WIN_Y,
						 XBUTTON_WIN_W, XBUTTON_WIN_H, MENU_STRING_PAL,  XBUTTON_VRAM_OFFSET );
	GF_BGL_BmpWinDataFill( XButtonWin, 0 );


	// メニュー文字列のBMPWIN確保
	for(i=0;i<MENU_EXPLAIN_NUM;i++){
		GF_BGL_BmpWinAdd( bgl, &ExplainBmp[i], GF_BGL_FRAME1_S,
						explain_bmp_xy[i][0],explain_bmp_xy[i][1],
						EXPLAIN_WIN_W, EXPLAIN_WIN_H, MENU_STRING_PAL,
						EXPLAIN_VRAM_OFFSET+(EXPLAIN_WIN_W*EXPLAIN_WIN_H)*i );
		GF_BGL_BmpWinDataFill( &ExplainBmp[i], 0 );

	}
}

//------------------------------------------------------------------
/**
 * @brief   下画面用セルアクター初期化
 *
 * @param   wk
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void InitCellActor(BEFORE_POKETCH_WORK *wk)
{
	enum{ MENU_ICON_PAL_SIZE = 16*2*2, };
	int i;

	// セルアクター初期化
	wk->clactSet = CLACT_U_SetEasyInit( MENU_ALL_OAM_NUM, &wk->renddata, HEAPID_SUBLCD_MENU );

	CLACT_U_SetSubSurfaceMatrix( &wk->renddata, 0, SUBLCD_MENU_SUB_ACTOR_DISTANCE );


	//リソースマネージャー初期化
	for(i=0;i<CLACT_RESOURCE_TYPE_NUM;i++){		//リソースマネージャー作成
		wk->resMan[i] = CLACT_U_ResManagerInit(CLACT_RESOURCE_CHARA_NUM, i, HEAPID_SUBLCD_MENU);
	}

	//---------下画面用リソース転送-------------------
	for(i=0;i<CLACT_RESOURCE_CHARA_NUM;i++){
		ClactResouceSet( wk->fsys, wk->resMan, wk->resObjTbl[i], i, SYSMENU_RES_ID+i,
						 MyStatus_GetMySex(SaveData_GetMyStatus( wk->fsys->savedata)),
						 SaveData_GetMyItem(wk->fsys->savedata), wk->menu_mode );
	}

	// アイコンセルデータ
	//cell読み込み
	wk->resObjTbl[0][CLACT_U_CELL_RES] = CLACT_U_ResManagerResAddArcKindCell(wk->resMan[CLACT_U_CELL_RES],
							ARC_SUBLCDMENU_GRA, NARC_poketch_oam001_lz_ncer, 1, SYSMENU_RES_ID, CLACT_U_CELL_RES,HEAPID_SUBLCD_MENU);

	//同じ関数でanim読み込み
	wk->resObjTbl[0][CLACT_U_CELLANM_RES] = CLACT_U_ResManagerResAddArcKindCell(wk->resMan[CLACT_U_CELLANM_RES],
							ARC_SUBLCDMENU_GRA, NARC_poketch_oam001_lz_nanr, 1, SYSMENU_RES_ID, CLACT_U_CELLANM_RES,HEAPID_SUBLCD_MENU);

	// Ａ・Ｂ・ショートカットボタン
	//cell読み込み
	wk->resObjTbl[1][CLACT_U_CELL_RES] = CLACT_U_ResManagerResAddArcKindCell(wk->resMan[CLACT_U_CELL_RES],
							ARC_SUBLCDMENU_GRA, NARC_poketch_menu_button_lz_ncer, 1, SYSMENU_RES_ID+1, CLACT_U_CELL_RES,HEAPID_SUBLCD_MENU);

	//同じ関数でanim読み込み
	wk->resObjTbl[1][CLACT_U_CELLANM_RES] = CLACT_U_ResManagerResAddArcKindCell(wk->resMan[CLACT_U_CELLANM_RES],
							ARC_SUBLCDMENU_GRA, NARC_poketch_menu_button_lz_nanr, 1, SYSMENU_RES_ID+1, CLACT_U_CELLANM_RES,HEAPID_SUBLCD_MENU);

	// ショートカットアイコンセルデータ
	//cell読み込み
	wk->resObjTbl[2][CLACT_U_CELL_RES] = CLACT_U_ResManagerResAddArcKindCell(wk->resMan[CLACT_U_CELL_RES],
							ARC_SUBLCDMENU_GRA, NARC_poketch_tsuri001_lz_ncer, 1, SYSMENU_RES_ID+2, CLACT_U_CELL_RES,HEAPID_SUBLCD_MENU);

	//同じ関数でanim読み込み
	wk->resObjTbl[2][CLACT_U_CELLANM_RES] = CLACT_U_ResManagerResAddArcKindCell(wk->resMan[CLACT_U_CELLANM_RES],
							ARC_SUBLCDMENU_GRA, NARC_poketch_tsuri001_lz_nanr, 1, SYSMENU_RES_ID+2, CLACT_U_CELLANM_RES,HEAPID_SUBLCD_MENU);

	// アイコンパレット書き換え用に保存しておく
	{
		void *adr;
		NNSG2dPaletteData *palData;
		adr = ArcUtil_PalDataGet( ARC_SUBLCDMENU_GRA, NARC_poketch_udmenu_oam01_nclr,
								  &palData, HEAPID_SUBLCD_MENU );
		DC_FlushRange( palData->pRawData, MENU_ICON_PAL_SIZE );
		MI_CpuCopyFast(palData->pRawData, wk->icon_pal, MENU_ICON_PAL_SIZE );
		sys_FreeMemoryEz( adr );
	}

}

//-----------------------------------------------------------------------------
/**
 *	@brief	モードに応じたボールのIDXを取得
 *
 *	@param	int menu_mode
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static int _get_ball_idx( int menu_mode )
{
	// @@@ 判定が分散してしまっている
	if( menu_mode == MENU_MODE_SAFARI )
	{
		return ITEM_SAFARIBOORU;
	}
	else if( menu_mode == MENU_MODE_PARK )
	{
		return ITEM_PAAKUBOORU;
	}
	else
	{
		return ITEM_KONPEBOORU;
	}
}

//------------------------------------------------------------------
/**
 * @brief   メニューが必要とするキャラとパレットを転送する
 *
 * @param   resMan		リソースマネージャ
 * @param   resObjTbl	リソースＯＢＪマネージャ
 * @param   resNo		読み込むリソースに当てるナンバー
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void ClactResouceSet( FIELDSYS_WORK* fsys, CLACT_U_RES_MANAGER_PTR* resMan, CLACT_U_RES_OBJ_PTR* resObjTbl, int no, int resNo, int sex, MYITEM *myitem, int menu_mode )
{
	u32 arcid;
	u32 readPal;
	u32 readChara;
	BOOL compflag;
	u8 pltt_num;

	int elem_idx = c_MenuListElemIdxTbl[ menu_mode ][no];

	arcid = ARC_SUBLCDMENU_GRA;
	readPal = NARC_poketch_udmenu_oam01_nclr;
	readChara = NARC_poketch_oam001_lz_ncgr; // 非表示にするのでダミー
	compflag = 1;
	pltt_num = 1;

	// メニュー用のCGXが用意されていれば読み込む
	if( elem_idx != MENU_LIST_ELEM_ID_NULL )
	{
		if( elem_idx == MENU_LIST_ELEM_ID_BAG && sex == PM_FEMALE )
		{
			// 女性用バッグに書き換え
			readPal   = NARC_poketch_udmenu_oam01_nclr;
			readChara = NARC_poketch_oam003b_lz_ncgr;
		}
		else
		{
			readChara = c_MenuListElem[ elem_idx ].cgr_idx;

			if( readChara == ELEM_CGX_HOOK_MUSHI_POKE )
			{
				FLD_MUSHITORI_WORK* mushi_wk;

				mushi_wk = MushitoriSysSt_GetWorkPointer( fsys );
				GF_ASSERT( mushi_wk );

				if( mushi_wk->get_f )
				{
					// ポケアイコンをロード
					arcid = ARC_POKEICON;
					compflag = 0;
					pltt_num = 3;

					readPal = PokeIconPalArcIndexGet();
					readChara = PokeIconCgxArcIndexGetByPP( mushi_wk->fld_pp );
				}
				else
				{
					readChara = NARC_poketch_oam001_lz_ncgr; // 非表示にするのでダミー
				}
			}
		}
	}

	//----------------------------------------------------------------------
	// メニューリスト以外の読み込み
	//----------------------------------------------------------------------
	// ショートカット1のアイテム読む込み
	if( no == RES_NO_SHORTCUT1 )
	{
		arcid = ARC_ITEMICON;
		compflag = 0;
		readPal = GetItemIndex( MyItem_CnvButtonItemGet(myitem), ITEM_GET_ICON_PAL );
		readChara = GetItemIndex( MyItem_CnvButtonItemGet(myitem), ITEM_GET_ICON_CGX );
	}
	// ショートカット2のアイテム読む込み
	else if( no == RES_NO_SHORTCUT2 )
	{
		arcid = ARC_ITEMICON;
		compflag = 0;
		readPal = GetItemIndex( MyItem_CnvButton2ItemGet(myitem), ITEM_GET_ICON_PAL );
		readChara = GetItemIndex( MyItem_CnvButton2ItemGet(myitem), ITEM_GET_ICON_CGX );
	}
	// ボタンの読み込み
	else if( no == RES_NO_BUTTON )
	{
		readPal = NARC_poketch_udmenu_bg_nclr;
		readChara = NARC_poketch_menu_button_lz_ncgr;
		pltt_num = 4;
	}
	// ボールの読み込み
	else if( no == RES_NO_BALL )
	{
		int item_idx = _get_ball_idx( menu_mode );
		arcid = ARC_ITEMICON;
		compflag = 0;
		readPal = GetItemIndex( item_idx, ITEM_GET_ICON_PAL );
		readChara = GetItemIndex( item_idx, ITEM_GET_ICON_CGX );
	}

	//----------------------------------------------------------------------
	//----------------------------------------------------------------------

	//chara読み込み
	resObjTbl[CLACT_U_CHAR_RES] = CLACT_U_ResManagerResAddArcChar(resMan[CLACT_U_CHAR_RES],
									arcid, readChara, compflag, resNo,
									NNS_G2D_VRAM_TYPE_2DSUB, HEAPID_SUBLCD_MENU);

	//pal読み込み
	resObjTbl[CLACT_U_PLTT_RES] = CLACT_U_ResManagerResAddArcPltt(resMan[CLACT_U_PLTT_RES],
									arcid, readPal, 0, resNo,
									NNS_G2D_VRAM_TYPE_2DSUB, pltt_num, HEAPID_SUBLCD_MENU);

	// リソースマネージャーから転送
	// Chara転送
	CLACT_U_CharManagerSetAreaCont( resObjTbl[CLACT_U_CHAR_RES] );

	// 読み込んだCharを破棄（転送が終了したので）
	CLACT_U_ResManagerResOnlyDelete( resObjTbl[CLACT_U_CHAR_RES] );

	// パレット転送
	CLACT_U_PlttManagerSetCleanArea( resObjTbl[CLACT_U_PLTT_RES] );

	// 読み込んだパレットを破棄（転送が終了したので）
	CLACT_U_ResManagerResOnlyDelete( resObjTbl[CLACT_U_PLTT_RES] );

}

// ＯＡＭ表示座標テーブル
static const u16 oam_pos_table[][2]={
	//---------------------------------------------
	// BGとのプライオリティ 0
	//---------------------------------------------
	{24,   24+OAM_DISP_DIFF,},	// 左上
	{24,   64+OAM_DISP_DIFF,},	// 左中1
	{24,  104+OAM_DISP_DIFF,},	// 左中2
	{24,  144+OAM_DISP_DIFF,},	// 左下
	{104,  24+OAM_DISP_DIFF,},	// 右上
	{104,  64+OAM_DISP_DIFF,},	// 右中1
	{104, 104+OAM_DISP_DIFF,},	// 右中2

	{220, 11},	// ショートカット1
	{220, 51},	// ショートカット2

	//---------------------------------------------
	// BGとのプライオリティ 2
	//---------------------------------------------
	{ 200,  8 },	// ショートカットの下地１
	{ 200, 48 },	// ショートカットの下地２

	{ 184, 86 },	// Ｂボタン
	{ 168,144 },	// Ａボタン

	{ 196+14, 94 },	// Ｂボタンの上のシンボル

	{ 46,     0}	// Ｘボタンアイコン
};

static const int cellanime_tbl[ CLACT_RESOURCE_CHARA_NUM ] = {
	// メニュー
	SYSMENU_RES_ID,SYSMENU_RES_ID,SYSMENU_RES_ID,SYSMENU_RES_ID,
	SYSMENU_RES_ID,SYSMENU_RES_ID,SYSMENU_RES_ID,
	// ショートカットアイコン
	SYSMENU_RES_ID+2,SYSMENU_RES_ID+2,
	// Ａ・Ｂ・ショートカットボタン
	SYSMENU_RES_ID+1,
	// ボール
	SYSMENU_RES_ID,
};

//------------------------------------------------------------------
/**
 * @brief   セルアクター表示登録
 *
 * @param   wk
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void SetCellActor(BEFORE_POKETCH_WORK *wk)
{
	int i;

	for(i=0;i<CLACT_RESOURCE_CHARA_NUM;i++){
		CLACT_U_MakeHeader(&wk->clActHeader_s[i],
		SYSMENU_RES_ID+i, SYSMENU_RES_ID+i,
		cellanime_tbl[i], cellanime_tbl[i], CLACT_U_HEADER_DATA_NONE, CLACT_U_HEADER_DATA_NONE,
		0, 0,
		wk->resMan[CLACT_U_CHAR_RES],
		wk->resMan[CLACT_U_PLTT_RES],
		wk->resMan[CLACT_U_CELL_RES],
		wk->resMan[CLACT_U_CELLANM_RES],
		NULL,NULL);
	}

	{
		//登録情報格納
		CLACT_ADD add;

		add.ClActSet	= wk->clactSet;
		add.ClActHeader	= &wk->clActHeader_s[0];

		add.mat.z		= 0;
		add.sca.x		= FX32_ONE;
		add.sca.y		= FX32_ONE;
		add.sca.z		= FX32_ONE;
		add.rot			= 0;
		add.pri			= 1;
		add.DrawArea	= NNS_G2D_VRAM_TYPE_2DSUB;
		add.heap		= HEAPID_SUBLCD_MENU;

		// セルアクター登録
		// メニュー7項目＋ショートカットアイコン2つ
		for(i=0;i<9;i++){
			add.ClActHeader	= &wk->clActHeader_s[i];
			add.mat.x		= FX32_CONST(oam_pos_table[i][0]) ;
			add.mat.y		= FX32_CONST(oam_pos_table[i][1]) + SUBLCD_MENU_SUB_ACTOR_DISTANCE;
			wk->MenuActWork[i] = CLACT_Add(&add);

			CLACT_SetAnmFlag(wk->MenuActWork[i],1);

			// BGとのプライオリティを0に下げる
			CLACT_BGPriorityChg( wk->MenuActWork[i], 0 );
			CLACT_SetAffineParam( wk->MenuActWork[i], CLACT_AFFINE_NORMAL );

		}

		// セルアクター登録
		for(i=9;i<15;i++){
			add.ClActHeader	= &wk->clActHeader_s[ RES_NO_BUTTON ];
			add.mat.x		= FX32_CONST(oam_pos_table[i][0]) ;
			add.mat.y		= FX32_CONST(oam_pos_table[i][1]) + SUBLCD_MENU_SUB_ACTOR_DISTANCE;
			wk->MenuActWork[i] = CLACT_Add(&add);
			CLACT_SetAnmFlag(wk->MenuActWork[i],1);

			// BGとのプライオリティを2に下げる
			CLACT_BGPriorityChg( wk->MenuActWork[i], 2 );
		}

		// ボール表示制御
		// @@@ elem と分散してしまっている。もっとやりようはあるはず
		if( wk->menu_mode == MENU_MODE_SAFARI || wk->menu_mode == MENU_MODE_MUSHITORI || wk->menu_mode == MENU_MODE_PARK )
		{
			s16 px, py;

			px = BALL_NUM_POS_X*8 + BALL_OBJ_OFS_DOT_X;

			if( wk->menu_mode == MENU_MODE_SAFARI )
			{
				py = BALL_NUM_POS7_Y * 8 + BALL_OBJ_OFS_DOT_Y;
			}
			else if( wk->menu_mode == MENU_MODE_MUSHITORI || wk->menu_mode == MENU_MODE_PARK )
			{
				py = BALL_NUM_POS6_Y * 8 + BALL_OBJ_OFS_DOT_Y;
			}

			add.ClActHeader	= &wk->clActHeader_s[ RES_NO_BALL ];
			add.mat.x		= FX32_CONST(px);
			add.mat.y		= FX32_CONST(py) + SUBLCD_MENU_SUB_ACTOR_DISTANCE;
			wk->MenuActWork[FMENU_OAM_BALL] = CLACT_Add(&add);

			CLACT_SetAnmFlag(wk->MenuActWork[FMENU_OAM_BALL], 1 );
			CLACT_BGPriorityChg( wk->MenuActWork[FMENU_OAM_BALL], 0 );

			// アニメセット( 4x4OAM用 )
			CLACT_AnmChg( wk->MenuActWork[FMENU_OAM_BALL], 6 );
		}

		// 虫取り大会 ポケモン表示(HOOKしたCGXに対する操作)
		// HOOKしたCGXに対する操作
		if( wk->menu_mode == MENU_MODE_MUSHITORI )
		{
			FLD_MUSHITORI_WORK* mushi_wk;
			u8 pal_ofs;

			mushi_wk = MushitoriSysSt_GetWorkPointer( wk->fsys );
			GF_ASSERT( mushi_wk );

			if( mushi_wk->get_f )
			{
				// ポケアイコンでフックするOBJの位置をずらす
				CATS_ObjectPosSet_SubSurface(
						wk->MenuActWork[FMENU_OAM_MUSHIPOKE], MUSHI_POKE_PX, MUSHI_POKE_PY, SUBLCD_MENU_SUB_ACTOR_DISTANCE );

				// パレットをずらす
				pal_ofs = PokeIconPalNumGetByPP( mushi_wk->fld_pp );
				CLACT_PaletteOffsetChgAddTransPlttNo( wk->MenuActWork[FMENU_OAM_MUSHIPOKE], pal_ofs );

				// アニメセット( 4x4OAM用 )
				CLACT_AnmChg( wk->MenuActWork[FMENU_OAM_MUSHIPOKE], 6 );
			}
		}
		// ポケパーク
		else if( wk->menu_mode == MENU_MODE_PARK )
		{
			// 非表示
			CLACT_SetDrawFlag( wk->MenuActWork[FMENU_OAM_POS_7], 0 );
		}

		// ボタン類
		CLACT_AnmChg(wk->MenuActWork[FMENU_OAM_SHORTCUT1_BG],0);
		CLACT_AnmChg(wk->MenuActWork[FMENU_OAM_SHORTCUT2_BG],8);
		CLACT_AnmChg(wk->MenuActWork[FMENU_OAM_B_BUTTON],3);
		CLACT_AnmChg(wk->MenuActWork[FMENU_OAM_A_BUTTON],5);
//		CLACT_AnmChg(wk->MenuActWork[FMENU_OAM_DASH_GEAR],7);
		CLACT_AnmChg(wk->MenuActWork[FMENU_OAM_X_ICON],12);

		CLACT_SetDrawFlag( wk->MenuActWork[FMENU_OAM_X_ICON], 0 );

		// ポケギア BGとのプライオリティを1に
		CLACT_BGPriorityChg( wk->MenuActWork[FMENU_OAM_DASH_GEAR], 1 );

		_dash_shoes_switch( wk );

		// ショートカットのアイコンを登録状況によってＯＮ／ＯＦＦする
		_icon_shortcut_set_draw( wk, 1 );
	}

	// メニューアイコンセルアクター表示制御
	_menu_icon_appear_init( wk );
}

// 6 3 0
// 7 4 1
// 8 5 2

// 0 4   7
// 1 5   8
// 2 6
// 3

// 上下左右の順
static const u8 move_pos_tbl[ MENU_ICON_NUM ][4][3]={
	{{ 3,2,1 },{ 1,2,3 },{ 4,0 },{ 4,0 }},	// 左の列の４つ
	{{ 0,3,2,},{ 2,3,0 },{ 5,1 },{ 5,1 }},
	{{ 1,0,3,},{ 3,0,1 },{ 6,2 },{ 6,2 }},
	{{ 2,1,0 },{ 0,1,2 },{ 6,3 },{ 6,3 }},

	{{ 6,5,4,},{ 5,6,4 },{ 0,4 },{ 0,4 }},	// 右の列の３つ
	{{ 4,6,5,},{ 6,4,5 },{ 1,5 },{ 1,5 }},
	{{ 5,4,6,},{ 4,5,6 },{ 2,6 },{ 2,6 }},
};

//------------------------------------------------------------------
/**
 * @brief   キー入力があった時、現在のアイテム表示状態で次はどこに
 *          移動するかを取得する
 *
 * @param   pos		現在の位置
 * @param   arrow	移動方向（上下左右が0-3に対応）
 * @param   info	項目が存在しているかのテーブル
 *
 * @retval  int		移動結果
 */
//------------------------------------------------------------------
static int NextCursorSearch(int pos, int arrow, MENU_EXIST_TBL exist[])
{
	int i,w,idx;
	w = -1;

	for(i=0;i<3;i++){
		idx = move_pos_tbl[pos][arrow][i];
		HOSAKA_PRINT("idx=%d,exist=%d\n",idx,exist[idx].exist);

		if(exist[idx].exist!=0){
			w = idx;
			break;
		}
	}
	return w;
}

//------------------------------------------------------------------
/**
 * @brief   対象のＯＢＪだけ違うパレットを転送する
 *			全部デフォルトに転送しなおす場合もある
 *
 * @param   bpw
 * @param   target	0-6:対象のパレットを転送　-1：全部デフォルトに
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _pal_trans( BEFORE_POKETCH_WORK *bpw, int target )
{
	int i;

	GF_ASSERT( target < MENU_ICON_NUM );

	for( i=0; i<MENU_ICON_NUM; i++ )
	{
		int elem_idx = c_MenuListElemIdxTbl[ bpw->menu_mode ][i];
		int cgr_idx = c_MenuListElem[ elem_idx ].cgr_idx;
		int pal_ofs = 0;

		// 空項目は飛ばす
		if( elem_idx == MENU_LIST_ELEM_ID_NULL ){ continue; }
		// 虫ポケモンも飛ばす
		if( cgr_idx == ELEM_CGX_HOOK_MUSHI_POKE ){ continue; }

		// 枠あり
		if( i == target )
		{
			pal_ofs = 16;
		}

		GXS_LoadOBJPltt( &bpw->icon_pal[ pal_ofs ], i*16*2, 32);
	}

}

//------------------------------------------------------------------
/**
 * @brief   カーソル移動
 *
 * @param   bpw
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void MenuControl( BEFORE_POKETCH_WORK *bpw )
{
	int arrow = -1, next = bpw->now_select;
	//---------------------------------------------------
	// キー入力でカーソル移動
	//---------------------------------------------------
	if( sys.trg & PAD_KEY_UP ){
		arrow =0;
	}else if( sys.trg & PAD_KEY_DOWN ){
		arrow =1;
	}else if( sys.trg & PAD_KEY_LEFT ){
		arrow =2;
	}else if( sys.trg & PAD_KEY_RIGHT ){
		arrow =3;
	}
	if(arrow>=0){
		next = NextCursorSearch( bpw->now_select, arrow, bpw->exist_tbl);
	}

	// 移動なし
	if(next == -1){	return; }

	// カーソルの移動が発生した
	if(bpw->now_select!=next){
		bpw->now_select = next;
		Snd_SePlay( SEQ_SE_DP_SELECT78 );	//メニュー選択音
		if(arrow==0 || arrow == 1){
			CLACT_AnmChg( bpw->MenuActWork[bpw->now_select], 3 );
		}else if(arrow==2 || arrow == 3){
			CLACT_AnmChg( bpw->MenuActWork[bpw->now_select], 1 );
		}
		// 選択中のアイコンのパレットを変える
		_pal_trans( bpw, bpw->now_select );
		// メインメニューにカーソル位置を伝える
		bpw->fsys->sublcd_menu_select = CalcPosIndexToMenuIndex( bpw, bpw->now_select );
		OS_Printf("now_select = %d\n", bpw->now_select);
	}
}


#define MENU_ICON_OAM_NUM	( 9 )

//-----------------------------------------------------------------------------
/**
 *	@brief	アクターのハイライト設定初期化
 *
 *	@param	CLACT_WORK_PTR ActWork[]
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void HighLightOamInit( CLACT_WORK_PTR ActWork[] )
{
	int i;

	for( i=0; i<MENU_ICON_NUM; i++ )
	{
		CLACT_ObjModeSet( ActWork[i], GX_OAM_MODE_NORMAL );
	}
}

//------------------------------------------------------------------
/**
 * @brief   アクターのハイライト処理
 *
 * @param   ActWork[]
 * @param   now
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void HighLightOamFunc( CLACT_WORK_PTR ActWork[], int now  )
{
	int i;

	for(i=0;i<MENU_ICON_OAM_NUM;i++){
		if( ActWork[i]!=NULL ){
			if(now!=i){
				CLACT_ObjModeSet( ActWork[i], GX_OAM_MODE_XLU	);
			}else{
				CLACT_ObjModeSet( ActWork[i], GX_OAM_MODE_NORMAL );
			}
		}
	}

#if 0
	if(sys.trg & PAD_BUTTON_R){
		for(i=0;i<8;i++){
			OS_Printf( "objmode%d = %d\n",	i, CLACT_ObjModeGet( ActWork[i]) );
		}
	}
#endif
}

#define	ALL_KEY		( PAD_KEY_UP | PAD_KEY_DOWN | PAD_KEY_LEFT | PAD_KEY_RIGHT )

//------------------------------------------------------------------
/**
 * @brief   タッチパネル処理
 *
 * @param   bpw
 *
 * @retval  int
 */
//------------------------------------------------------------------
static int TouchControl( BEFORE_POKETCH_WORK *bpw )
{
	// タッチ判定座標定義配列
	static const RECT_HIT_TBL SubLcdMenuHitTbl[]={
		{ 0,	8*2,	8*1,	8*20},	// Ｘメニュー

		{ 8*3+OAM_DISP_DIFF,	8*7+OAM_DISP_DIFF,	8*2,	8*9+4},		// 左上
		{ 8*8+OAM_DISP_DIFF,	8*12+OAM_DISP_DIFF,	8*2,	8*9+4},		// 左中１
		{ 8*13+OAM_DISP_DIFF,	8*17+OAM_DISP_DIFF,	8*2,	8*9+4},		// 左中２
		{ 8*18+OAM_DISP_DIFF,	8*22+OAM_DISP_DIFF,	8*2,	8*9+4},		// 左下

		{ 8*3+OAM_DISP_DIFF,	8*7+OAM_DISP_DIFF,	8*12,	8*19+4},	// 右上
		{ 8*8+OAM_DISP_DIFF,	8*12+OAM_DISP_DIFF,	8*12,	8*19+4},	// 右中
		{ 8*13+OAM_DISP_DIFF,	8*17+OAM_DISP_DIFF,	8*12,	8*19+4},	// 右下

		{  8, 39, 203,255},		// ショートカット1
		{ 46, 77, 203,255},		// ショートカット2

		{RECT_HIT_END,0,0,0},
	};

	int tp_hit;
	int st;

	st = Player_MoveStateGet( bpw->fsys->player );		// 自機の状態

	// 自機動作中は反応させない
	if( st != OBJ_MOVE_STATE_OFF || (sys.trg & ALL_KEY) )
	{
		return 1;
	}

	// コロシアム(通信部屋)
	if( bpw->menu_mode == MENU_MODE_COLOSSEUM )
	{
		int CurrentID = CommGetCurrentID();

		// タッチ抑制
		if(
			CommDirectIsMoveState() == FALSE ||	// 移動位置にいない
			CommFieldStateIsCopyEnd() == FALSE ||	// データコピーが終わっていない
			CommPlayerManagerIsInitialize() == FALSE || // 通信プレイヤークラスが初期化されていない
			CommPlayerIsControl() == FALSE ||	// プレイヤーキャラが通信状態にない
//			CommPlayerIsMyMoveControl() == FALSE ||	// 自機が移動可能でない
			CommPlayerGetWalkCount(CurrentID) ||
			CommSysIsMoveKey() // キーを送ったかどうか
		)
		{
			return 1;
		}
	}

	// ワイプ中は反応しない
	if(WIPE_SYS_EndCheck()==FALSE){ return 1; }

	// 選択後は反応させない
	if( bpw->menu_enter == 1 ){ return 1; }

	tp_hit = GF_TP_RectHitTrg( SubLcdMenuHitTbl );

#if 0 // PM_DEBUG
	// デバッグキー押しっぱなしで強制タッチ
	if( sys.cont & PAD_BUTTON_DEBUG )
	{
		tp_hit = 1;
	}
#endif

	// メニューが無効なものが選択された場合は処理を抜ける
	if( tp_hit > 0 && tp_hit < MENU_ICON_NUM+1 )
	{
		if( bpw->exist_tbl[tp_hit-1].exist == 0 ) { return 0; }
	}

	// 登録状況によってショートカット無効
	{
		MYITEM* myitem = SaveData_GetMyItem( bpw->fsys->savedata );

		// 共通チェック
		if( tp_hit == 8 || tp_hit == 9 )
		{
			if (bpw->b_KeyButtonEnable == 0 ){ return 1; }
			if( CheckShortCutEnable(bpw) == FALSE ){ return 1; }
		}

		if( tp_hit == 8 )
		{
			if (MyItem_CnvButtonItemGet( myitem ) == 0 ){ return 1; }
		}
		else if( tp_hit == 9 )
		{
			if (MyItem_CnvButton2ItemGet( myitem ) == 0 ){ return 1; }
		}
	}

	if(tp_hit!=RECT_HIT_NONE){

		// メインメニューを開いて無い状態で「Xメニュー」をタッチした
		if(tp_hit==0){
			*bpw->panel_trg = SUBLCD_TOUCH_OPEN_MENU;
		}else{
			// 直接アイコンをタッチした
#if PM_DEBUG
			GF_ASSERT( tp_hit > 0 && tp_hit < 10 );
			GF_ASSERT( bpw->MenuActWork[tp_hit-1] );
#endif
			if( bpw->MenuActWork[tp_hit-1] != NULL ) {
				// ショートカット以外なら
				if( tp_hit < MENU_ICON_NUM+1 ) {
					// now_select を更新
					bpw->now_select = tp_hit-1;
					// メインメニューにカーソル位置を伝える
					bpw->fsys->sublcd_menu_select = CalcPosIndexToMenuIndex( bpw, bpw->now_select );
					// 選択中のアイコンのパレットを変える
					_pal_trans( bpw, bpw->now_select );
				}

				// メインメニューにタッチ情報を伝える
				*bpw->panel_trg = SUBLCD_TOUCH_POS1 + CalcPosIndexToMenuIndex(bpw, tp_hit-1);

				HOSAKA_PRINT("menu::set panel_trg:%d \n",*bpw->panel_trg);
			}
		}

		return 0;
	}
	return 1;
}


// アイコン説明
static const u8 icontbl[]={
	 32+12, 	 32+13,	 32+14,		//
	 64+12, 	     0,	 64+14,		//
	 96+12, 	     0,	 96+14,		//
	128+12, 	128+13,	128+14,		//
};

// 電話がかかってきたとき
static const u8 phonetbl[]={
	160+ 9, 	160+10, 	160+11,160+12,	160+13,		//
	 96+ 4, 	 96+ 5, 	 96+ 6,     0,	 96+ 8,		//
	128+ 4, 	128+ 5, 	128+ 6,     0,	128+ 8,		//
	160+ 4, 	160+ 5,		160+ 6,160+ 7,	160+ 8,		//
};

//------------------------------------------------------------------
/**
 * @brief   アイコン説明文の周りにウインドウフレームを描画する
 *
 * @param   MenuBmp		GF_BGL_BMPWIN
 * @param   flag		ICON_WIN_WRITE=アイコン用：PHONE_WIN_WRITE=電話用
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void IconWinWrite( GF_BGL_BMPWIN *MenuBmp, int flag )
{
	int px,py,sx,sy,pal;
	GF_BGL_INI *ini = MenuBmp->ini;
	u8	frm = GF_BGL_BmpWinGet_Frame( MenuBmp );
	px = GF_BGL_BmpWinGet_PosX( MenuBmp );
	py = GF_BGL_BmpWinGet_PosY( MenuBmp);
	sx = GF_BGL_BmpWinGet_SizeX(MenuBmp);
	sy = GF_BGL_BmpWinGet_SizeY(MenuBmp);
	pal = 2;

	switch(flag)
	{
		case ICON_WIN_WRITE :
			GF_BGL_ScrFill( ini, frm, icontbl[0], px-1,  py-1, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, icontbl[1], px,    py-1, sx, 1, pal );
			GF_BGL_ScrFill( ini, frm, icontbl[2], px+sx, py-1, 1,  1, pal );

			GF_BGL_ScrFill( ini, frm, icontbl[3], px-1,  py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, icontbl[5], px+sx, py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, icontbl[6], px-1,  py+1, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, icontbl[8], px+sx, py+1, 1, 1, pal );

			GF_BGL_ScrFill( ini, frm, icontbl[9], px-1,   py+sy, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, icontbl[10], px,    py+sy, sx, 1, pal );
			GF_BGL_ScrFill( ini, frm, icontbl[11], px+sx, py+sy, 1,  1, pal );
			break;

		case PHONE_WIN_WRITE :
			GF_BGL_ScrFill( ini, frm, phonetbl[0], px-3,  py-1, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[1], px-2,  py-1, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[2], px-1,  py-1, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[3], px,    py-1, sx, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[4], px+sx, py-1, 1,  1, pal );

			GF_BGL_ScrFill( ini, frm, phonetbl[5], px-3,  py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[6], px-2,  py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[7], px-1,  py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[9], px+sx, py, 1, 1, pal );

			GF_BGL_ScrFill( ini, frm, phonetbl[10], px-3,  py+1, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[11], px-2,  py+1, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[12], px-1,  py+1, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[14], px+sx, py+1, 1, 1, pal );

			GF_BGL_ScrFill( ini, frm, phonetbl[15], px-3,  py+sy, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[16], px-2,  py+sy, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[17], px-1,  py+sy, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[18], px,    py+sy, sx, 1, pal );
			GF_BGL_ScrFill( ini, frm, phonetbl[19], px+sx, py+sy, 1,  1, pal );
			break;

		case PHONE_WIN_CLEAR :
			GF_BGL_ScrFill( ini, frm, 0, px-3,  py-1, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-2,  py-1, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-1,  py-1, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px,    py-1, sx, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px+sx, py-1, 1,  1, pal );

			GF_BGL_ScrFill( ini, frm, 0, px-3,  py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-2,  py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-1,  py, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px+sx, py, 1, 1, pal );

			GF_BGL_ScrFill( ini, frm, 0, px-3,  py+1, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-2,  py+1, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-1,  py+1, 1, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px+sx, py+1, 1, 1, pal );

			GF_BGL_ScrFill( ini, frm, 0, px-3,  py+sy, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-2,  py+sy, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px-1,  py+sy, 1,  1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px,    py+sy, sx, 1, pal );
			GF_BGL_ScrFill( ini, frm, 0, px+sx, py+sy, 1,  1, pal );
			break;

		default : GF_ASSERT(0);
	}
}

//------------------------------------------------------------------
/**
 * @brief   メニュー説明文字列の描画
 *
 * @param   MenuBmp		BMPWIN
 * @param   string		描画する文字列
 * @param   type		ICON_WIN_WRITE=アイコン用：PHONE_WIN_WRITE=電話用
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void MenuStringDraw( GF_BGL_BMPWIN *MenuBmp, STRBUF *string, int type )
{
	static const GF_PRINTCOLOR col[]={
		GF_PRINTCOLOR_MAKE( 14,7,15), GF_PRINTCOLOR_MAKE( 5, 4, 3),
	};

	GF_BGL_BmpWinDataFill( MenuBmp, col[type]&GF_PRINTCOLOR_MASK );
	// 文字列描画（センタリング対応）
	GF_STR_PrintColor(	MenuBmp, FONT_SYSTEM, string,
						3, 0,
//						(MENU_STRING_W*8-FontProc_GetPrintStrWidth( FONT_SYSTEM, string, 0 ))/2, 0,
						MSG_ALLPUT,	col[type], NULL );
}

//------------------------------------------------------------------
/**
 * @brief   メニュー文字列の取得と表示開始時の文字列の描画
 *
 * @param   bpw
 * @param   flag	描画している面では文字描画の必要があるか？
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void MenuStringSet( BEFORE_POKETCH_WORK *bpw, int flag )
{
	int i;

	// 現在メニューが示している文字列を取得（名前展開込み）
	MYSTATUS *mystatus = SaveData_GetMyStatus(bpw->fsys->savedata);
	WORDSET_RegisterPlayerName( bpw->WordSet, 0, mystatus );

	for(i=0;i<MENU_ICON_NUM;i++)
	{
		int msg_idx;
		int elem_idx = c_MenuListElemIdxTbl[ bpw->menu_mode ][i];

		// 空は飛ばす
		if( elem_idx == MENU_LIST_ELEM_ID_NULL ){ continue; }

		msg_idx = c_MenuListElem[ elem_idx ].msg_idx;

		bpw->exist_tbl[i].String =
			MSGDAT_UTIL_AllocExpandString( bpw->WordSet, bpw->msgman, msg_idx, HEAPID_SUBLCD_MENU);
	}

	// Aボタンでできる事
	for(i=0;i<ACTION_STRING_MAX;i++){
		bpw->ActionStr[i] = MSGMAN_AllocString( bpw->msgman, action_str_tbl[i] );
	}
#ifdef PRINT_HEAP_SIZE
	// 「メニュー」の変わりに heap_size を表示 (FINAL_ROM用)
	{
		HEAPID heapID = HEAPID_SUBLCD_MENU;
		WORDSET* wset = bpw->WordSet;
		MSGDATA_MANAGER* msgman = bpw->msgman;
		STRBUF* tempbuf = STRBUF_Create( 128, heapID );
		STRBUF* dstbuf = STRBUF_Create( 128, heapID );
		int heap_size = sys_GetHeapFreeSize( HEAPID_BASE_APP );
		int tcb_stack_num = DebugTCBSys_GetStackNum( sys.mainTCBSys );
//		int remain = (u32)(OS_GetMainArenaHi())-(u32)(OS_GetMainArenaLo());

		WORDSET_RegisterNumber( wset, 0, heap_size, 6, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( wset, 1, tcb_stack_num, 3, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		MSGMAN_GetString( msgman, msg_menu_mem, tempbuf );
		WORDSET_ExpandStr( wset, dstbuf, tempbuf );

		STRBUF_Delete( tempbuf );

		bpw->XButtonStr[0] = dstbuf;
	}
#else
	bpw->XButtonStr[0] = MSGDAT_UTIL_AllocExpandString( bpw->WordSet, bpw->msgman,  msg_menu_12, HEAPID_SUBLCD_MENU);
#endif
	bpw->XButtonStr[1] = MSGDAT_UTIL_AllocExpandString( bpw->WordSet, bpw->msgman,  msg_menu_13, HEAPID_SUBLCD_MENU);
}

//------------------------------------------------------------------
/**
 * @brief   取得したメニュー文字列の解放
 *
 * @param   bpw
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void MenuStringRelase( BEFORE_POKETCH_WORK *bpw )
{
	int i;

	STRBUF_Delete( bpw->XButtonStr[1] );
	STRBUF_Delete( bpw->XButtonStr[0] );

	for(i=0;i<ACTION_STRING_MAX;i++){
		STRBUF_Delete( bpw->ActionStr[i] );
	}

	for(i=0;i<MENU_ICON_NUM;i++){
		// 空は飛ばす
		if( bpw->exist_tbl[i].String ){
			STRBUF_Delete( bpw->exist_tbl[i].String );
		}
	}

}

//---------------------- -------------------------------------------
/**
 * @brief   イベントフラグを見て説明文字列を表示制御する
 *
 * @param   bpw
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void ExplainStringAppear( BEFORE_POKETCH_WORK *wk )
{
	int drawflag[MENU_EXPLAIN_NUM],i;
	int count=0;

	// メニュー文字列を表示するか取得
	for(i=0;i<MENU_EXPLAIN_NUM;i++){
		drawflag[i] = FldMenu_ExecuteCheck( wk->fsys, i );
	}

	// フラグによって文字列表示を反映させる
	for(i=0;i<MENU_EXPLAIN_NUM;i++){
		if(drawflag[i]){
			GF_BGL_BmpWinOn( &wk->ExplainBmp[i] );
			count++;
		}
	}

	// もしもメニューが一つも表示されない場合は「メニュー」文字列も描画しない
	if(count){
		CLACT_SetDrawFlag( wk->MenuActWork[FMENU_OAM_X_ICON], 1 );
		GF_BGL_BmpWinOn( &wk->XButtonWin );
	}

}

//------------------------------------------------------------------
/**
 * @brief   メニュー文字列描画
 *
 * @param   wk
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void ExplainStringDraw( BEFORE_POKETCH_WORK *wk )
{
	int i;

	for(i=0;i<MENU_ICON_NUM;i++){
		int width;

		// 空だったら飛ばす
		if( wk->exist_tbl[i].String == NULL ){ continue; }

		width = EXPLAIN_WIN_W * 8 - FontProc_GetPrintStrWidth( FONT_SYSTEM, wk->exist_tbl[i].String, 0 );
		width /= 2;

		// 文字列描画（センタリング対応）
		GF_STR_PrintColor(	&wk->ExplainBmp[i], FONT_SYSTEM, wk->exist_tbl[i].String,
					width, 0, MSG_NO_PUT, GF_PRINTCOLOR_MAKE(14,2,0), NULL );

	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	会話中判定
 *
 *	@param	FIELDSYS_WORK* fsys
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static BOOL CheckTalking( FIELDSYS_WORK* fsys )
{
	// 「つぎへ」フラグを監視
	return fsys->sublcd_menu_next_flag;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メニューモードを判定
 *
 *	@param	FIELDSYS_WORK fsys
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static u8 CheckMenuMode( FIELDSYS_WORK* fsys )
{
	EVENTWORK* ev = SaveData_GetEventWork( fsys->savedata );

	if( BtlTower_IsSalon( fsys ) )
	{
		return MENU_MODE_BTL_TOWER_SALON;
	}
	else if( SysFlag_SafariCheck(ev) )
	{
		return MENU_MODE_SAFARI;
	}
	else if( SysFlag_MushitoriCheck(ev) )
	{
		return MENU_MODE_MUSHITORI;
	}
	else if( SysFlag_PokeParkCheck(ev) )
	{
		return MENU_MODE_PARK;
	}
	else if( fsys->subscreen == FIELD_SUBSCRN_UNION )
	{
		return MENU_MODE_UNION;
	}
	else if( fsys->MapMode == MAP_MODE_COLOSSEUM )
	{
		return MENU_MODE_COLOSSEUM;
	}

	return MENU_MODE_NORMAL;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ショートカットが有効なモードか
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static BOOL CheckShortCutEnable( BEFORE_POKETCH_WORK* bpw )
{
	return (bpw->menu_mode != MENU_MODE_PARK && bpw->menu_mode != MENU_MODE_UNION &&
			bpw->menu_mode != MENU_MODE_COLOSSEUM && bpw->menu_mode != MENU_MODE_MUSHITORI &&
			bpw->menu_mode != MENU_MODE_BTL_TOWER_SALON );
}

//------------------------------------------------------------------
/**
 * @brief   主人公がダッシュシューズを取得しているか
 *
 * @param   wk
 *
 * @retval  BOOL	0:取得してない	1:取得してる
 */
//------------------------------------------------------------------
static BOOL _player_shoes_check( BEFORE_POKETCH_WORK *wk )
{
	SITUATION *situ = SaveData_GetSituation( wk->fsys->savedata );
	PLAYER_SAVE_DATA *jikisave = Situation_GetPlayerSaveData( situ );

	return Player_SaveDataDashCheck( jikisave );
}


//-----------------------------------------------------------------------------
/**
 *	@brief	電話着信モジュール初期化
 *
 *	@param	PHONE_WORK* wk
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phone_Init( PHONE_WORK* wk, BEFORE_POKETCH_WORK* bpw )
{
	wk->pmtel = FldPMTel_PointerGet( bpw->fsys );
	wk->MenuAct = bpw->MenuActWork[FMENU_OAM_POKEGEAR];
	wk->bgl = bpw->bgl;
	wk->tel_flag = 0;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	電話着信モジュール 主処理
 *
 *	@param	PHONE_WORK* wk
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phone_Proc( PHONE_WORK* wk )
{
	BOOL b_callup = FldPMTel_CallupFlagGet(wk->pmtel);

	if( wk->tel_flag == 0 )
	{
		// 着信開始
		if( b_callup == TRUE )
		{
			// 着信相手の名前表示ウィンドウ生成
			STRBUF* strbuf;
			int width;

			// 既に呼びだされているウインドウがある場合は呼ばない
			if( wk->tel_flag ){ return; }

			strbuf = FldPMTel_CallNameStrAlloc( wk->pmtel, HEAPID_SUBLCD_MENU );
			// 文字列表示に使うキャラ数を取得
			width = FontProc_GetPrintStrWidth( FONT_SYSTEM, strbuf, 0 );
			width = (width/8) + 2;

			// メニュー説明文字列用BMPWIN確保
			GF_BGL_BmpWinAdd( wk->bgl, &wk->MenuBmp, GF_BGL_FRAME1_S,
				TEL_WIN_PX,  TEL_WIN_PY, width, MENU_STRING_H, MENU_STRING_PAL, MENU_STRING_VRAM_OFFSET );

			IconWinWrite( &wk->MenuBmp, PHONE_WIN_WRITE );

			MenuStringDraw( &wk->MenuBmp, strbuf, PHONE_WIN_WRITE );

			STRBUF_Delete(strbuf);

			// 着信アニメ開始
			CLACT_AnmChgCheck( wk->MenuAct, 5 );

			wk->tel_flag = 1;
		}
	}
	else
	{
		// 着信中
		if( b_callup )
		{
			// 着信アニメ オーバーライド
			CLACT_AnmChgCheck( wk->MenuAct, 5 );
		}
		//  着信終了
		else
		{
			// 着信アニメ終了
			CLACT_AnmChgCheck( wk->MenuAct, 0 );
			Phone_Close( wk );
			wk->tel_flag = 0;
		}
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	電話着信モジュール 強制終了→画面遷移
 *
 *	@param	PHONE_WORK* wk
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phone_Close( PHONE_WORK* wk )
{
	if( wk->tel_flag )
	{
		IconWinWrite( &wk->MenuBmp, PHONE_WIN_CLEAR );
		GF_BGL_BmpWinOff( &wk->MenuBmp );
		GF_BGL_BmpWinDel( &wk->MenuBmp );
	}
}

#define DOT_X_CENTER ( -1 ) // dxをセンタリング指定

// 文字列描画＆転送
static void _print_exception_core( BEFORE_POKETCH_WORK* bpw, int msg_idx, u8 px, u8 py, u8 sx, u8 sy, int vram_ofs, s16 dx, s16 dy )
{
	STRBUF* strbuf;
	GF_BGL_BMPWIN win;

	GF_BGL_BmpWinAdd( bpw->bgl, &win, GF_BGL_FRAME1_S, px, py, sx, sy, MENU_STRING_PAL, vram_ofs );
	GF_BGL_BmpWinDataFill( &win, 0 );

	strbuf = MSGDAT_UTIL_AllocExpandString( bpw->WordSet, bpw->msgman, msg_idx, HEAPID_SUBLCD_MENU );

	// センタリング
	if( dx == DOT_X_CENTER )
	{
		dx = sx * 8 - FontProc_GetPrintStrWidth( FONT_SYSTEM, strbuf, 0 );
		dx /= 2;
	}

	GF_STR_PrintColor( &win, FONT_SYSTEM, strbuf, dx, dy, MSG_NO_PUT, GF_PRINTCOLOR_MAKE(14,2,0), NULL );

	STRBUF_Delete( strbuf );
	GF_BGL_BmpWinOn( &win );
	GF_BGL_BmpWinDel( &win );
}

// ボール個数用 文字列表示
static void _print_ball_num( BEFORE_POKETCH_WORK*bpw, u8 px, u8 py, const u16 ball_count )
{
	WORDSET_RegisterNumber( bpw->WordSet, 0, ball_count, 2, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );
	_print_exception_core( bpw, msg_menu_31, px, py, BALL_NUM_WIN_W, BALL_NUM_WIN_H, BALL_NUM_VRAM_OFFSET, 0, 0 );
}

// ポケモンレベル 文字列表示
static void _print_poke_level( BEFORE_POKETCH_WORK* bpw, FLD_MUSHITORI_WORK* mushi_wk )
{
	int level = PokeParaGet( mushi_wk->fld_pp, ID_PARA_level, NULL );

	WORDSET_RegisterNumber( bpw->WordSet, 0, level, 3, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );

	_print_exception_core(
			bpw, msg_menu_33,
			POKE_LV_WIN_PX, POKE_LV_WIN_PY, POKE_LV_WIN_W, POKE_LV_WIN_H,
			POKE_LV_VRAM_OFFSET, POKE_LV_OFS_X, 0 );
}

// 8つめの項目位置に「ボール」を描画
static void _print_ball_str_to_pos8( BEFORE_POKETCH_WORK* bpw )
{
	_print_exception_core(
			bpw, msg_menu_32,
			EXPLAIN7_WIN_X, EXPLAIN7_WIN_Y, EXPLAIN_WIN_W, EXPLAIN_WIN_H,
			EXPLAIN_VRAM_OFFSET+(EXPLAIN_WIN_W*EXPLAIN_WIN_H)*7,
			DOT_X_CENTER, 0 );
}

// 例外表示 サファリ
static void _exception_safari( BEFORE_POKETCH_WORK* bpw )
{
	SITUATION *situ = SaveData_GetSituation( bpw->fsys->savedata );
	u16* ball_count = Situation_GetSafariBallCount( situ );

	_print_ball_num( bpw, BALL_NUM_POS_X, BALL_NUM_POS7_Y, *ball_count );
	_print_ball_str_to_pos8( bpw );
}

// 例外表示 パルパーク
static void _exception_park( BEFORE_POKETCH_WORK* bpw )
{
	int ball_count = PokeParkSys_GetBallCount( bpw->fsys );

	_print_ball_num( bpw, BALL_NUM_POS_X, BALL_NUM_POS6_Y, ball_count );
}

// 例外表示 虫取り
static void _exception_mushitori( BEFORE_POKETCH_WORK* bpw )
{
	FLD_MUSHITORI_WORK* mushi_wk;
	u16* ball_count;

	mushi_wk = MushitoriSysSt_GetWorkPointer( bpw->fsys );
	GF_ASSERT( mushi_wk );

	ball_count = MushitoriSysSt_GetBallNumPointer( mushi_wk );

	_print_ball_num( bpw, BALL_NUM_POS_X, BALL_NUM_POS6_Y, *ball_count );

	// ポケモンを取得しているかチェック
	if( mushi_wk->get_f )
	{
		_print_poke_level( bpw, mushi_wk );
	}

	CLACT_SetDrawFlag( bpw->MenuActWork[ FMENU_OAM_MUSHIPOKE ], mushi_wk->get_f );

	// 虫でフックする位置を常に無効化
	bpw->old_appear_flag[FMENU_OAM_MUSHIPOKE] = 0;
	bpw->exist_tbl[FMENU_OAM_MUSHIPOKE].exist = 0;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	モード毎の例外表示
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void MenuList_PrintException( BEFORE_POKETCH_WORK* bpw )
{
	if( bpw->menu_mode == MENU_MODE_SAFARI )
	{
		_exception_safari(bpw);
	}
	else if( bpw->menu_mode == MENU_MODE_MUSHITORI )
	{
		_exception_mushitori(bpw);
	}
	else if( bpw->menu_mode == MENU_MODE_PARK )
	{
		_exception_park(bpw);
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	項目の有効無効判定
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void MenuList_SetExist( BEFORE_POKETCH_WORK* bpw )
{
	int i;

	// メニュー項目のON/OFF設定
	for( i=0; i<MENU_ICON_NUM; i++ )
	{
		int elem_idx;

		elem_idx = c_MenuListElemIdxTbl[bpw->menu_mode][i];

		if( elem_idx != MENU_LIST_ELEM_ID_NULL )
		{
			if( elem_idx < MENU_ICON_NUM )
			{
				// ※MENU_LIST_ELEM と FLD_APPEAR_XXX で順番を一致させている
				bpw->old_appear_flag[i] = FldMenu_ExecuteCheck( bpw->fsys, elem_idx );
			}
			else
			{
				bpw->old_appear_flag[i] = c_MenuListElem[ elem_idx ].b_exist;
			}
		}
		bpw->exist_tbl[i].exist = bpw->old_appear_flag[i];
		HOSAKA_PRINT("[%d]exist=%d\n",i, bpw->exist_tbl[i].exist);
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メニューのPOSインデックスを項目インデックスに変更
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *	@param	pos_idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static int CalcPosIndexToMenuIndex( BEFORE_POKETCH_WORK* bpw, int pos_idx )
{
	int i;
	int ret = -1;

	// ショートカットはスルー
	if( pos_idx == 7 || pos_idx == 8 )
	{
		return pos_idx;
	}

	for( i=0; i<pos_idx+1; i++ )
	{
		if( bpw->exist_tbl[i].exist )
		{
			ret++;
		}
	}

	GF_ASSERT( ret != -1 );

	HOSAKA_PRINT( "sublcd_pos:%d to menu_pos:%d \n", pos_idx, ret );

	return ret;
}


//-----------------------------------------------------------------------------
/**
 *	@brief	メニューIDから座標IDに換算
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *	@param	menu_idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static int CalcMenuIndexToPosIndex( BEFORE_POKETCH_WORK* bpw, int menu_idx )
{
	int i;
	int ret = -1;
	int count = 0;

	// 換算
	for( i=0; i<MENU_ICON_NUM; i++ )
	{
		if( bpw->exist_tbl[i].exist )
		{
			if( menu_idx == count )
			{
				ret = i;
				break;
			}
			else
			{
				count++;
			}
		}
	}

	// 範囲外
	if( ret == -1 )
	{
		ret = 0;
		bpw->fsys->sublcd_menu_select = ret;
	}

	HOSAKA_PRINT( "sublcd_menu_select:%d to now_select:%d \n",bpw->fsys->sublcd_menu_select, ret );

	return ret;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	無効な場所を選んでいたら頭から有効箇所を検索
 *
 *	@param	BEFORE_POKETCH_WORK* bpw
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void CheckSortMenuIndex( BEFORE_POKETCH_WORK* bpw )
{
	GF_ASSERT( bpw->fsys );

	if( bpw->exist_tbl[ bpw->now_select ].exist == FALSE )
	{
		int i;
		for( i=0; i<MENU_ICON_NUM; i++ )
		{
			if( bpw->exist_tbl[i].exist )
			{
				HOSAKA_PRINT("recalc! pre sublcd_menu_select :%d \n", bpw->fsys->sublcd_menu_select);
				bpw->fsys->sublcd_menu_select = i;
				bpw->now_select = CalcMenuIndexToPosIndex(bpw, bpw->fsys->sublcd_menu_select);
				HOSAKA_PRINT("recalced sublcd_menu_select :%d \n", bpw->fsys->sublcd_menu_select);
				break;
			}
		}
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	不正対策用メモリアロック関数
 */
//-----------------------------------------------------------------------------
static void MagiconFunc(void)
{
	sys_AllocMemoryLo( HEAPID_BASE_APP, 1000 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	正規ロム版関数
 */
//-----------------------------------------------------------------------------
static void NotMagiconFunc1(void)
{
}

//-----------------------------------------------------------------------------
/**
 *	@brief	正規ロム版関数
 */
//-----------------------------------------------------------------------------
static void NotMagiconFunc2(void)
{
}


#if 0

//------------------------------------------------------------------
/**
 * @brief   ジョウト図鑑を手に入れたフラグのチェック
 *
 * @param   wk
 *
 * @retval  BOOL	TRUEで手に入れている
 */
//------------------------------------------------------------------
static BOOL _zukan_event_check( BEFORE_POKETCH_WORK *wk )
{
	return SysFlag_JohtoZukanGet( SaveData_GetEventWork(wk->fsys->savedata ));

}

//------------------------------------------------------------------
/**
 * @brief   最初のポケモンを手に入れたフラグチェック
 *
 * @param   wk
 *
 * @retval  BOOL	TRUEで手に入れている
 */
//------------------------------------------------------------------
static BOOL _first_poke_check( BEFORE_POKETCH_WORK *wk )
{
	return SysFlag_FirstPokeGet( SaveData_GetEventWork(wk->fsys->savedata ));

}

//------------------------------------------------------------------
/**
 * @brief   ポケギアを手に入れたかフラグチェック
 *
 * @param   wk
 *
 * @retval  BOOL
 */
//------------------------------------------------------------------
static BOOL _pokegear_event_check( BEFORE_POKETCH_WORK *wk )
{
	// ここをポケギアフラグに変える
	return SysFlag_PokeGearGet( SaveData_GetEventWork(wk->fsys->savedata ));
}

#endif

#if 0
static int debugobj=0;
//==============================================================================
/**
 * @brief   OBJの座標確認をするルーチン
 *
 * @param   wk
 *
 * @retval  none
 */
//==============================================================================
static void menu_obj_test( BEFORE_POKETCH_WORK *wk )
{
	VecFx32 mat;

	mat.x = CLACT_GetMatrix( wk->MenuActWork[debugobj] )->x;
	mat.y = CLACT_GetMatrix( wk->MenuActWork[debugobj] )->y;
	if(sys.cont & PAD_KEY_UP){
		mat.y-=FX32_ONE;
		CLACT_SetMatrix( wk->MenuActWork[debugobj], &mat );
		OS_Printf("obj x=%d, y=%d\n", mat.x/FX32_ONE,mat.y/FX32_ONE);

	}else if(sys.cont & PAD_KEY_DOWN){
		mat.y+=FX32_ONE;
		CLACT_SetMatrix( wk->MenuActWork[debugobj], &mat );
		OS_Printf("obj x=%d, y=%d\n", mat.x/FX32_ONE,mat.y/FX32_ONE);
	}else if(sys.cont & PAD_KEY_LEFT){
		mat.x-=FX32_ONE;
		CLACT_SetMatrix( wk->MenuActWork[debugobj], &mat );
		OS_Printf("obj x=%d, y=%d\n", mat.x/FX32_ONE,mat.y/FX32_ONE);
	}else if(sys.cont & PAD_KEY_RIGHT){
		mat.x+=FX32_ONE;
		CLACT_SetMatrix( wk->MenuActWork[debugobj], &mat );
		OS_Printf("obj x=%d, y=%d\n", mat.x/FX32_ONE,mat.y/FX32_ONE);
	}else if(sys.trg & PAD_BUTTON_SELECT){
		if(++debugobj>8){
			debugobj=0;
		}
	}
}

#endif

#if 0
static int debugx=0,debugy=0;
//==============================================================================
/**
 * @brief   OBJの座標確認をするルーチン
 *
 * @param   wk
 *
 * @retval  none
 */
//==============================================================================
static void menu_bg_test( BEFORE_POKETCH_WORK *wk )
{

	if(sys.cont & PAD_KEY_UP){
		debugy--;
		GF_BGL_ScrollSet( wk->bgl, GF_BGL_FRAME1_S,GF_BGL_SCROLL_Y_SET, debugy );
		OS_Printf("obj x=%d, y=%d\n", debugx, debugy);

	}else if(sys.cont & PAD_KEY_DOWN){
		debugy++;
		GF_BGL_ScrollSet( wk->bgl, GF_BGL_FRAME1_S,GF_BGL_SCROLL_Y_SET, debugy );
		OS_Printf("obj x=%d, y=%d\n", debugx, debugy);
	}else if(sys.cont & PAD_KEY_LEFT){
		debugx--;
		GF_BGL_ScrollSet( wk->bgl, GF_BGL_FRAME1_S,GF_BGL_SCROLL_X_SET, debugx );
		OS_Printf("obj x=%d, y=%d\n", debugx, debugy);
	}else if(sys.cont & PAD_KEY_RIGHT){
		debugx++;
		GF_BGL_ScrollSet( wk->bgl, GF_BGL_FRAME1_S,GF_BGL_SCROLL_X_SET, debugx );
		OS_Printf("obj x=%d, y=%d\n", debugx, debugy);
	}
}
#endif
